summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBrian Paul <brianp@vmware.com>2012-05-08 11:41:03 -0600
committerBrian Paul <brianp@vmware.com>2012-05-11 16:13:14 -0600
commit1bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651 (patch)
treec66295b3f10537f9543ffea9afb08fef8eaddb92 /src
parentf2724905469bbcde820b9ece2e4f44a610a75a65 (diff)
mesa: fix glMaterial / dlist bug
When glColorMaterial() is used to latch glColor commands to a material attribute, glMaterial calls to change that material should become no-ops. This failed to work properly when the glMaterial call was inside a display list. This removes the Material function from the vbo_attrib_tmp.h template file. We have separate/different implementations for the "save" and "exec" cases now. NOTE: This is a candidate for the 8.0 branch.
Diffstat (limited to 'src')
-rw-r--r--src/mesa/vbo/vbo_attrib_tmp.h58
-rw-r--r--src/mesa/vbo/vbo_exec_api.c95
-rw-r--r--src/mesa/vbo/vbo_save_api.c57
3 files changed, 152 insertions, 58 deletions
diff --git a/src/mesa/vbo/vbo_attrib_tmp.h b/src/mesa/vbo/vbo_attrib_tmp.h
index 0bf5c91658d..d3fc77eefde 100644
--- a/src/mesa/vbo/vbo_attrib_tmp.h
+++ b/src/mesa/vbo/vbo_attrib_tmp.h
@@ -792,63 +792,6 @@ TAG(VertexAttrib4fvNV)(GLuint index, const GLfloat * v)
}
-
-#define MAT( ATTR, N, face, params ) \
-do { \
- if (face != GL_BACK) \
- MAT_ATTR( ATTR, N, params ); /* front */ \
- if (face != GL_FRONT) \
- MAT_ATTR( ATTR + 1, N, params ); /* back */ \
-} while (0)
-
-
-/* Colormaterial conflicts are dealt with later.
- */
-static void GLAPIENTRY
-TAG(Materialfv)(GLenum face, GLenum pname,
- const GLfloat * params)
-{
- GET_CURRENT_CONTEXT(ctx);
-
- if (face != GL_FRONT && face != GL_BACK && face != GL_FRONT_AND_BACK) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glMaterial(invalid face)");
- return;
- }
-
- switch (pname) {
- case GL_EMISSION:
- MAT(VBO_ATTRIB_MAT_FRONT_EMISSION, 4, face, params);
- break;
- case GL_AMBIENT:
- MAT(VBO_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params);
- break;
- case GL_DIFFUSE:
- MAT(VBO_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params);
- break;
- case GL_SPECULAR:
- MAT(VBO_ATTRIB_MAT_FRONT_SPECULAR, 4, face, params);
- break;
- case GL_SHININESS:
- if (*params < 0 || *params > ctx->Const.MaxShininess)
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glMaterial(invalid shininess: %f out range [0, %f])",
- *params, ctx->Const.MaxShininess);
- else
- MAT(VBO_ATTRIB_MAT_FRONT_SHININESS, 1, face, params);
- break;
- case GL_COLOR_INDEXES:
- MAT(VBO_ATTRIB_MAT_FRONT_INDEXES, 3, face, params);
- break;
- case GL_AMBIENT_AND_DIFFUSE:
- MAT(VBO_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params);
- MAT(VBO_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params);
- break;
- default:
- ERROR(GL_INVALID_ENUM);
- return;
- }
-}
-
static void GLAPIENTRY
TAG(VertexP2ui)(GLenum type, GLuint value)
{
@@ -1145,4 +1088,3 @@ TAG(VertexAttribP4uiv)(GLuint index, GLenum type, GLboolean normalized,
#undef ATTR_UI
#undef MAT
-#undef MAT_ATTR
diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c
index b87da18f3eb..0fd8d591517 100644
--- a/src/mesa/vbo/vbo_exec_api.c
+++ b/src/mesa/vbo/vbo_exec_api.c
@@ -433,6 +433,101 @@ do { \
#include "vbo_attrib_tmp.h"
+
+/**
+ * Execute a glMaterial call. Note that if GL_COLOR_MATERIAL is enabled,
+ * this may be a (partial) no-op.
+ */
+static void GLAPIENTRY
+vbo_Materialfv(GLenum face, GLenum pname, const GLfloat *params)
+{
+ GLbitfield updateMats;
+ GET_CURRENT_CONTEXT(ctx);
+
+ /* This function should be a no-op when it tries to update material
+ * attributes which are currently tracking glColor via glColorMaterial.
+ * The updateMats var will be a mask of the MAT_BIT_FRONT/BACK_x bits
+ * indicating which material attributes can actually be updated below.
+ */
+ if (ctx->Light.ColorMaterialEnabled) {
+ updateMats = ~ctx->Light.ColorMaterialBitmask;
+ }
+ else {
+ /* GL_COLOR_MATERIAL is disabled so don't skip any material updates */
+ updateMats = ALL_MATERIAL_BITS;
+ }
+
+ if (face == GL_FRONT) {
+ updateMats &= FRONT_MATERIAL_BITS;
+ }
+ else if (face == GL_BACK) {
+ updateMats &= BACK_MATERIAL_BITS;
+ }
+ else if (face != GL_FRONT_AND_BACK) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glMaterial(invalid face)");
+ return;
+ }
+
+ switch (pname) {
+ case GL_EMISSION:
+ if (updateMats & MAT_BIT_FRONT_EMISSION)
+ MAT_ATTR(VBO_ATTRIB_MAT_FRONT_EMISSION, 4, params);
+ if (updateMats & MAT_BIT_BACK_EMISSION)
+ MAT_ATTR(VBO_ATTRIB_MAT_BACK_EMISSION, 4, params);
+ break;
+ case GL_AMBIENT:
+ if (updateMats & MAT_BIT_FRONT_AMBIENT)
+ MAT_ATTR(VBO_ATTRIB_MAT_FRONT_AMBIENT, 4, params);
+ if (updateMats & MAT_BIT_BACK_AMBIENT)
+ MAT_ATTR(VBO_ATTRIB_MAT_BACK_AMBIENT, 4, params);
+ break;
+ case GL_DIFFUSE:
+ if (updateMats & MAT_BIT_FRONT_DIFFUSE)
+ MAT_ATTR(VBO_ATTRIB_MAT_FRONT_DIFFUSE, 4, params);
+ if (updateMats & MAT_BIT_BACK_DIFFUSE)
+ MAT_ATTR(VBO_ATTRIB_MAT_BACK_DIFFUSE, 4, params);
+ break;
+ case GL_SPECULAR:
+ if (updateMats & MAT_BIT_FRONT_SPECULAR)
+ MAT_ATTR(VBO_ATTRIB_MAT_FRONT_SPECULAR, 4, params);
+ if (updateMats & MAT_BIT_BACK_SPECULAR)
+ MAT_ATTR(VBO_ATTRIB_MAT_BACK_SPECULAR, 4, params);
+ break;
+ case GL_SHININESS:
+ if (*params < 0 || *params > ctx->Const.MaxShininess) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glMaterial(invalid shininess: %f out range [0, %f])",
+ *params, ctx->Const.MaxShininess);
+ return;
+ }
+ if (updateMats & MAT_BIT_FRONT_SHININESS)
+ MAT_ATTR(VBO_ATTRIB_MAT_FRONT_SHININESS, 1, params);
+ if (updateMats & MAT_BIT_BACK_SHININESS)
+ MAT_ATTR(VBO_ATTRIB_MAT_BACK_SHININESS, 1, params);
+ break;
+ case GL_COLOR_INDEXES:
+ if (updateMats & MAT_BIT_FRONT_INDEXES)
+ MAT_ATTR(VBO_ATTRIB_MAT_FRONT_INDEXES, 3, params);
+ if (updateMats & MAT_BIT_BACK_INDEXES)
+ MAT_ATTR(VBO_ATTRIB_MAT_BACK_INDEXES, 3, params);
+ break;
+ case GL_AMBIENT_AND_DIFFUSE:
+ if (updateMats & MAT_BIT_FRONT_AMBIENT)
+ MAT_ATTR(VBO_ATTRIB_MAT_FRONT_AMBIENT, 4, params);
+ if (updateMats & MAT_BIT_FRONT_DIFFUSE)
+ MAT_ATTR(VBO_ATTRIB_MAT_FRONT_DIFFUSE, 4, params);
+ if (updateMats & MAT_BIT_BACK_AMBIENT)
+ MAT_ATTR(VBO_ATTRIB_MAT_BACK_AMBIENT, 4, params);
+ if (updateMats & MAT_BIT_BACK_DIFFUSE)
+ MAT_ATTR(VBO_ATTRIB_MAT_BACK_DIFFUSE, 4, params);
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glMaterialfv(pname)");
+ return;
+ }
+}
+
+
/**
* Flush (draw) vertices.
* \param unmap - leave VBO unmapped after flushing?
diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c
index 74f5dc9ce68..f202375caa4 100644
--- a/src/mesa/vbo/vbo_save_api.c
+++ b/src/mesa/vbo/vbo_save_api.c
@@ -724,6 +724,63 @@ do { \
+#define MAT( ATTR, N, face, params ) \
+do { \
+ if (face != GL_BACK) \
+ MAT_ATTR( ATTR, N, params ); /* front */ \
+ if (face != GL_FRONT) \
+ MAT_ATTR( ATTR + 1, N, params ); /* back */ \
+} while (0)
+
+
+/**
+ * Save a glMaterial call found between glBegin/End.
+ * glMaterial calls outside Begin/End are handled in dlist.c.
+ */
+static void GLAPIENTRY
+_save_Materialfv(GLenum face, GLenum pname, const GLfloat *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (face != GL_FRONT && face != GL_BACK && face != GL_FRONT_AND_BACK) {
+ _mesa_compile_error(ctx, GL_INVALID_ENUM, "glMaterial(face)");
+ return;
+ }
+
+ switch (pname) {
+ case GL_EMISSION:
+ MAT(VBO_ATTRIB_MAT_FRONT_EMISSION, 4, face, params);
+ break;
+ case GL_AMBIENT:
+ MAT(VBO_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params);
+ break;
+ case GL_DIFFUSE:
+ MAT(VBO_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params);
+ break;
+ case GL_SPECULAR:
+ MAT(VBO_ATTRIB_MAT_FRONT_SPECULAR, 4, face, params);
+ break;
+ case GL_SHININESS:
+ if (*params < 0 || *params > ctx->Const.MaxShininess) {
+ _mesa_compile_error(ctx, GL_INVALID_VALUE, "glMaterial(shininess)");
+ }
+ else {
+ MAT(VBO_ATTRIB_MAT_FRONT_SHININESS, 1, face, params);
+ }
+ break;
+ case GL_COLOR_INDEXES:
+ MAT(VBO_ATTRIB_MAT_FRONT_INDEXES, 3, face, params);
+ break;
+ case GL_AMBIENT_AND_DIFFUSE:
+ MAT(VBO_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params);
+ MAT(VBO_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params);
+ break;
+ default:
+ _mesa_compile_error(ctx, GL_INVALID_ENUM, "glMaterial(pname)");
+ return;
+ }
+}
+
/* Cope with EvalCoord/CallList called within a begin/end object:
* -- Flush current buffer