src/video/SDL_renderer_gl.c
changeset 3468 789b97008d8a
parent 3458 0aed0755d1f1
child 3470 419f459f2f38
equal deleted inserted replaced
3467:383c2058d973 3468:789b97008d8a
   173     PFNGLGENPROGRAMSARBPROC glGenProgramsARB;
   173     PFNGLGENPROGRAMSARBPROC glGenProgramsARB;
   174     PFNGLBINDPROGRAMARBPROC glBindProgramARB;
   174     PFNGLBINDPROGRAMARBPROC glBindProgramARB;
   175     PFNGLPROGRAMSTRINGARBPROC glProgramStringARB;
   175     PFNGLPROGRAMSTRINGARBPROC glProgramStringARB;
   176 
   176 
   177     /* (optional) fragment programs */
   177     /* (optional) fragment programs */
       
   178     GLuint fragment_program_mask;
   178     GLuint fragment_program_UYVY;
   179     GLuint fragment_program_UYVY;
   179 } GL_RenderData;
   180 } GL_RenderData;
   180 
   181 
   181 typedef struct
   182 typedef struct
   182 {
   183 {
   482 }
   483 }
   483 
   484 
   484 
   485 
   485 //#define DEBUG_PROGRAM_COMPILE 1
   486 //#define DEBUG_PROGRAM_COMPILE 1
   486 
   487 
       
   488 static void
       
   489 set_shader_error(GL_RenderData * data, const char *prefix)
       
   490 {
       
   491     GLint pos = 0;
       
   492     const GLubyte *errstr;
       
   493     data->glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos);
       
   494     errstr = data->glGetString(GL_PROGRAM_ERROR_STRING_ARB);
       
   495     printf("%s: shader compile error at position %d: %s",
       
   496            prefix, (int) pos, (const char *) errstr);
       
   497 }
       
   498 
   487 static GLuint
   499 static GLuint
   488 compile_shader(GL_RenderData * data, GLenum shader_type, const char *_code)
   500 compile_shader(GL_RenderData * data, GLenum shader_type, const char *_code)
   489 {
   501 {
   490     const int have_texture_rects = data->GL_ARB_texture_rectangle_supported;
   502     const int have_texture_rects = data->GL_ARB_texture_rectangle_supported;
   491     const char *replacement = have_texture_rects ? "RECT" : "2D";
   503     const char *replacement = have_texture_rects ? "RECT" : "2D";
   538     }
   550     }
   539 
   551 
   540     return program;
   552     return program;
   541 }
   553 }
   542 
   554 
       
   555 
       
   556 /*
       
   557  * Fragment program that implements mask semantics
       
   558  */
       
   559 static const char *fragment_program_mask_source_code = "!!ARBfp1.0\n"
       
   560 "OUTPUT output = result.color;\n"
       
   561 "TEMP value;\n"
       
   562 "TEX value, fragment.texcoord[0], texture[0], %TEXTURETARGET%;\n"
       
   563 "MUL value, fragment.color, value;\n"
       
   564 "SGE value.a, value.a, 0.001;\n"
       
   565 "MOV output, value;\n"
       
   566 "END";
   543 
   567 
   544 /*
   568 /*
   545  * Fragment program that renders from UYVY textures.
   569  * Fragment program that renders from UYVY textures.
   546  * The UYVY to RGB equasion is:
   570  * The UYVY to RGB equasion is:
   547  *   R = 1.164(Y-16) + 1.596(Cr-128)
   571  *   R = 1.164(Y-16) + 1.596(Cr-128)
   749         if (renderdata->fragment_program_UYVY == 0) {
   773         if (renderdata->fragment_program_UYVY == 0) {
   750             renderdata->fragment_program_UYVY =
   774             renderdata->fragment_program_UYVY =
   751                 compile_shader(renderdata, GL_FRAGMENT_PROGRAM_ARB,
   775                 compile_shader(renderdata, GL_FRAGMENT_PROGRAM_ARB,
   752                                fragment_program_UYVY_source_code);
   776                                fragment_program_UYVY_source_code);
   753             if (renderdata->fragment_program_UYVY == 0) {
   777             if (renderdata->fragment_program_UYVY == 0) {
   754                 SDL_SetError("Fragment program compile error");
   778                 set_shader_error(renderdata, "UYVY");
   755                 return -1;
   779                 return -1;
   756             }
   780             }
   757         }
   781         }
   758         shader = renderdata->fragment_program_UYVY;
   782         shader = renderdata->fragment_program_UYVY;
   759     }
   783     }
  1160 GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
  1184 GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
  1161               const SDL_Rect * srcrect, const SDL_Rect * dstrect)
  1185               const SDL_Rect * srcrect, const SDL_Rect * dstrect)
  1162 {
  1186 {
  1163     GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
  1187     GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
  1164     GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata;
  1188     GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata;
       
  1189     GLuint shader = 0;
  1165     int minx, miny, maxx, maxy;
  1190     int minx, miny, maxx, maxy;
  1166     GLfloat minu, maxu, minv, maxv;
  1191     GLfloat minu, maxu, minv, maxv;
  1167 
  1192 
  1168     if (texturedata->dirty.list) {
  1193     if (texturedata->dirty.list) {
  1169         SDL_DirtyRect *dirty;
  1194         SDL_DirtyRect *dirty;
  1212     } else {
  1237     } else {
  1213         data->glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
  1238         data->glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
  1214     }
  1239     }
  1215 
  1240 
  1216     GL_SetBlendMode(data, texture->blendMode, 0);
  1241     GL_SetBlendMode(data, texture->blendMode, 0);
       
  1242 
       
  1243     /* Set up the shader for the copy, we have a special one for MASK */
       
  1244     shader = texturedata->shader;
       
  1245     if (texture->blendMode == SDL_BLENDMODE_MASK && !shader) {
       
  1246         if (data->fragment_program_mask == 0) {
       
  1247             data->fragment_program_mask =
       
  1248                 compile_shader(data, GL_FRAGMENT_PROGRAM_ARB,
       
  1249                                fragment_program_mask_source_code);
       
  1250             if (data->fragment_program_mask == 0) {
       
  1251                 /* That's okay, we'll just miss some of the blend semantics */
       
  1252                 data->fragment_program_mask = ~0;
       
  1253             }
       
  1254         }
       
  1255         if (data->fragment_program_mask != ~0) {
       
  1256             shader = data->fragment_program_mask;
       
  1257         }
       
  1258     }
  1217 
  1259 
  1218     if (texture->scaleMode != data->scaleMode) {
  1260     if (texture->scaleMode != data->scaleMode) {
  1219         switch (texture->scaleMode) {
  1261         switch (texture->scaleMode) {
  1220         case SDL_TEXTURESCALEMODE_NONE:
  1262         case SDL_TEXTURESCALEMODE_NONE:
  1221         case SDL_TEXTURESCALEMODE_FAST:
  1263         case SDL_TEXTURESCALEMODE_FAST:
  1233             break;
  1275             break;
  1234         }
  1276         }
  1235         data->scaleMode = texture->scaleMode;
  1277         data->scaleMode = texture->scaleMode;
  1236     }
  1278     }
  1237 
  1279 
  1238     if (texturedata->shader != 0) {
  1280     if (shader) {
  1239         data->glEnable(GL_FRAGMENT_PROGRAM_ARB);
  1281         data->glEnable(GL_FRAGMENT_PROGRAM_ARB);
  1240         data->glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, texturedata->shader);
  1282         data->glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, shader);
  1241     }
  1283     }
  1242 
  1284 
  1243     data->glBegin(GL_TRIANGLE_STRIP);
  1285     data->glBegin(GL_TRIANGLE_STRIP);
  1244     data->glTexCoord2f(minu, minv);
  1286     data->glTexCoord2f(minu, minv);
  1245     data->glVertex2f(0.5f + minx, 0.5f + miny);
  1287     data->glVertex2f(0.5f + minx, 0.5f + miny);
  1249     data->glVertex2f(0.5f + minx, 0.5f + maxy);
  1291     data->glVertex2f(0.5f + minx, 0.5f + maxy);
  1250     data->glTexCoord2f(maxu, maxv);
  1292     data->glTexCoord2f(maxu, maxv);
  1251     data->glVertex2f(0.5f + maxx, 0.5f + maxy);
  1293     data->glVertex2f(0.5f + maxx, 0.5f + maxy);
  1252     data->glEnd();
  1294     data->glEnd();
  1253 
  1295 
  1254     if (texturedata->shader != 0) {
  1296     if (shader) {
  1255         data->glDisable(GL_FRAGMENT_PROGRAM_ARB);
  1297         data->glDisable(GL_FRAGMENT_PROGRAM_ARB);
  1256     }
  1298     }
  1257 
  1299 
  1258     data->glDisable(texturedata->type);
  1300     data->glDisable(texturedata->type);
  1259 
  1301 
  1375     if (data) {
  1417     if (data) {
  1376         if (data->context) {
  1418         if (data->context) {
  1377             if (data->GL_ARB_fragment_program_supported) {
  1419             if (data->GL_ARB_fragment_program_supported) {
  1378                 data->glDisable(GL_FRAGMENT_PROGRAM_ARB);
  1420                 data->glDisable(GL_FRAGMENT_PROGRAM_ARB);
  1379                 data->glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0);
  1421                 data->glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0);
  1380                 if (data->fragment_program_UYVY != 0) {
  1422                 if (data->fragment_program_mask &&
       
  1423                     data->fragment_program_mask != ~0) {
       
  1424                     data->glDeleteProgramsARB(1,
       
  1425                                               &data->fragment_program_mask);
       
  1426                 }
       
  1427                 if (data->fragment_program_UYVY &&
       
  1428                     data->fragment_program_UYVY != ~0) {
  1381                     data->glDeleteProgramsARB(1,
  1429                     data->glDeleteProgramsARB(1,
  1382                                               &data->fragment_program_UYVY);
  1430                                               &data->fragment_program_UYVY);
  1383                 }
  1431                 }
  1384             }
  1432             }
  1385 
  1433