If binding a NULL program, disable any vertex arrays we previously enabled.
This is done in case the caller is switching to the fixed function pipeline
and needs more control over the vertex arrays.
So to minimize state changes, don't bind a NULL program between draws if
you're just going to bind a new program later.
--- a/mojoshader_opengl.c Tue Mar 30 20:12:29 2010 -0400
+++ b/mojoshader_opengl.c Wed Mar 31 02:08:36 2010 -0400
@@ -1585,6 +1585,35 @@
} // MOJOSHADER_glLinkProgram
+static void update_enabled_arrays(void)
+{
+ int highest_enabled = 0;
+ int i;
+
+ // Enable/disable vertex arrays to match our needs.
+ // this happens to work in both ARB1 and GLSL, but if something alien
+ // shows up, we'll have to split these into profile*() functions.
+ for (i = 0; i <= ctx->max_attrs; i++)
+ {
+ const int want = (const int) ctx->want_attr[i];
+ const int have = (const int) ctx->have_attr[i];
+ if (want != have)
+ {
+ if (want)
+ ctx->glEnableVertexAttribArray(i);
+ else
+ ctx->glDisableVertexAttribArray(i);
+ ctx->have_attr[i] = ctx->want_attr[i];
+ } // if
+
+ if (want)
+ highest_enabled = i;
+ } // for
+
+ ctx->max_attrs = highest_enabled; // trim unneeded iterations next time.
+} // update_enabled_arrays
+
+
void MOJOSHADER_glBindProgram(MOJOSHADER_glProgram *program)
{
GLuint handle = 0;
@@ -1600,6 +1629,12 @@
memset(ctx->want_attr, '\0', sizeof (ctx->want_attr[0]) * ctx->max_attrs);
+ // If no program bound, disable all arrays, in case we're switching to
+ // fixed function pipeline. Otherwise, we try to minimize state changes
+ // by toggling just the changed set of needed arrays in ProgramReady().
+ if (program == NULL)
+ update_enabled_arrays();
+
ctx->profileUseProgramObject(program);
program_unref(ctx->bound_program);
ctx->bound_program = program;
@@ -1771,35 +1806,6 @@
} // MOJOSHADER_glSetVertexAttribute
-static void update_enabled_arrays(void)
-{
- int highest_enabled = 0;
- int i;
-
- // Enable/disable vertex arrays to match our needs.
- // this happens to work in both ARB1 and GLSL, but if something alien
- // shows up, we'll have to split these into profile*() functions.
- for (i = 0; i <= ctx->max_attrs; i++)
- {
- const int want = (const int) ctx->want_attr[i];
- const int have = (const int) ctx->have_attr[i];
- if (want != have)
- {
- if (want)
- ctx->glEnableVertexAttribArray(i);
- else
- ctx->glDisableVertexAttribArray(i);
- ctx->have_attr[i] = ctx->want_attr[i];
- } // if
-
- if (want)
- highest_enabled = i;
- } // for
-
- ctx->max_attrs = highest_enabled; // trim unneeded iterations next time.
-} // update_enabled_arrays
-
-
void MOJOSHADER_glProgramReady(void)
{
MOJOSHADER_glProgram *program = ctx->bound_program;
@@ -1910,7 +1916,6 @@
MOJOSHADER_glContext *current_ctx = ctx;
ctx = _ctx;
MOJOSHADER_glBindProgram(NULL);
- update_enabled_arrays(); // disables all vertex arrays.
lookup_entry_points(NULL, NULL);
Free(ctx);
ctx = ((current_ctx == _ctx) ? NULL : current_ctx);