Commit 335b4597 authored by Sam Lantinga's avatar Sam Lantinga

My first OpenGL shader! Momma will be so proud!

This shader implements the software renderer mask semantics where the source pixel is multiplied by the color and alpha modulation values and then any pixel with non-zero alpha is fully opaque.

The OpenGL renderer on Mac OS X now passes all the automated render tests! :)

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%404209
parent 22c1e661
...@@ -175,6 +175,7 @@ typedef struct ...@@ -175,6 +175,7 @@ typedef struct
PFNGLPROGRAMSTRINGARBPROC glProgramStringARB; PFNGLPROGRAMSTRINGARBPROC glProgramStringARB;
/* (optional) fragment programs */ /* (optional) fragment programs */
GLuint fragment_program_mask;
GLuint fragment_program_UYVY; GLuint fragment_program_UYVY;
} GL_RenderData; } GL_RenderData;
...@@ -484,6 +485,17 @@ power_of_2(int input) ...@@ -484,6 +485,17 @@ power_of_2(int input)
//#define DEBUG_PROGRAM_COMPILE 1 //#define DEBUG_PROGRAM_COMPILE 1
static void
set_shader_error(GL_RenderData * data, const char *prefix)
{
GLint pos = 0;
const GLubyte *errstr;
data->glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos);
errstr = data->glGetString(GL_PROGRAM_ERROR_STRING_ARB);
printf("%s: shader compile error at position %d: %s",
prefix, (int) pos, (const char *) errstr);
}
static GLuint static GLuint
compile_shader(GL_RenderData * data, GLenum shader_type, const char *_code) compile_shader(GL_RenderData * data, GLenum shader_type, const char *_code)
{ {
...@@ -541,6 +553,18 @@ compile_shader(GL_RenderData * data, GLenum shader_type, const char *_code) ...@@ -541,6 +553,18 @@ compile_shader(GL_RenderData * data, GLenum shader_type, const char *_code)
} }
/*
* Fragment program that implements mask semantics
*/
static const char *fragment_program_mask_source_code = "!!ARBfp1.0\n"
"OUTPUT output = result.color;\n"
"TEMP value;\n"
"TEX value, fragment.texcoord[0], texture[0], %TEXTURETARGET%;\n"
"MUL value, fragment.color, value;\n"
"SGE value.a, value.a, 0.001;\n"
"MOV output, value;\n"
"END";
/* /*
* Fragment program that renders from UYVY textures. * Fragment program that renders from UYVY textures.
* The UYVY to RGB equasion is: * The UYVY to RGB equasion is:
...@@ -751,7 +775,7 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) ...@@ -751,7 +775,7 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
compile_shader(renderdata, GL_FRAGMENT_PROGRAM_ARB, compile_shader(renderdata, GL_FRAGMENT_PROGRAM_ARB,
fragment_program_UYVY_source_code); fragment_program_UYVY_source_code);
if (renderdata->fragment_program_UYVY == 0) { if (renderdata->fragment_program_UYVY == 0) {
SDL_SetError("Fragment program compile error"); set_shader_error(renderdata, "UYVY");
return -1; return -1;
} }
} }
...@@ -1162,6 +1186,7 @@ GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, ...@@ -1162,6 +1186,7 @@ GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
{ {
GL_RenderData *data = (GL_RenderData *) renderer->driverdata; GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata; GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata;
GLuint shader = 0;
int minx, miny, maxx, maxy; int minx, miny, maxx, maxy;
GLfloat minu, maxu, minv, maxv; GLfloat minu, maxu, minv, maxv;
...@@ -1215,6 +1240,23 @@ GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, ...@@ -1215,6 +1240,23 @@ GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
GL_SetBlendMode(data, texture->blendMode, 0); GL_SetBlendMode(data, texture->blendMode, 0);
/* Set up the shader for the copy, we have a special one for MASK */
shader = texturedata->shader;
if (texture->blendMode == SDL_BLENDMODE_MASK && !shader) {
if (data->fragment_program_mask == 0) {
data->fragment_program_mask =
compile_shader(data, GL_FRAGMENT_PROGRAM_ARB,
fragment_program_mask_source_code);
if (data->fragment_program_mask == 0) {
/* That's okay, we'll just miss some of the blend semantics */
data->fragment_program_mask = ~0;
}
}
if (data->fragment_program_mask != ~0) {
shader = data->fragment_program_mask;
}
}
if (texture->scaleMode != data->scaleMode) { if (texture->scaleMode != data->scaleMode) {
switch (texture->scaleMode) { switch (texture->scaleMode) {
case SDL_TEXTURESCALEMODE_NONE: case SDL_TEXTURESCALEMODE_NONE:
...@@ -1235,9 +1277,9 @@ GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, ...@@ -1235,9 +1277,9 @@ GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
data->scaleMode = texture->scaleMode; data->scaleMode = texture->scaleMode;
} }
if (texturedata->shader != 0) { if (shader) {
data->glEnable(GL_FRAGMENT_PROGRAM_ARB); data->glEnable(GL_FRAGMENT_PROGRAM_ARB);
data->glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, texturedata->shader); data->glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, shader);
} }
data->glBegin(GL_TRIANGLE_STRIP); data->glBegin(GL_TRIANGLE_STRIP);
...@@ -1251,7 +1293,7 @@ GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, ...@@ -1251,7 +1293,7 @@ GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
data->glVertex2f(0.5f + maxx, 0.5f + maxy); data->glVertex2f(0.5f + maxx, 0.5f + maxy);
data->glEnd(); data->glEnd();
if (texturedata->shader != 0) { if (shader) {
data->glDisable(GL_FRAGMENT_PROGRAM_ARB); data->glDisable(GL_FRAGMENT_PROGRAM_ARB);
} }
...@@ -1377,7 +1419,13 @@ GL_DestroyRenderer(SDL_Renderer * renderer) ...@@ -1377,7 +1419,13 @@ GL_DestroyRenderer(SDL_Renderer * renderer)
if (data->GL_ARB_fragment_program_supported) { if (data->GL_ARB_fragment_program_supported) {
data->glDisable(GL_FRAGMENT_PROGRAM_ARB); data->glDisable(GL_FRAGMENT_PROGRAM_ARB);
data->glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0); data->glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0);
if (data->fragment_program_UYVY != 0) { if (data->fragment_program_mask &&
data->fragment_program_mask != ~0) {
data->glDeleteProgramsARB(1,
&data->fragment_program_mask);
}
if (data->fragment_program_UYVY &&
data->fragment_program_UYVY != ~0) {
data->glDeleteProgramsARB(1, data->glDeleteProgramsARB(1,
&data->fragment_program_UYVY); &data->fragment_program_UYVY);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment