diff --git a/doc/makepanda/makepanda71.vcproj b/doc/makepanda/makepanda71.vcproj
index 0932878016..eb1ee2a0c4 100755
--- a/doc/makepanda/makepanda71.vcproj
+++ b/doc/makepanda/makepanda71.vcproj
@@ -17,8 +17,8 @@
ConfigurationType="0">
+ BuildCommandLine="cd .. & makepanda\makepanda --everything"
+ Output="..\built\python\python.exe"/>
diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx
index 17b3ba40b5..aee7e3554e 100644
--- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx
+++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx
@@ -757,6 +757,8 @@ reset() {
_current_shader_context = (CLP(ShaderContext) *)NULL;
_vertex_array_shader_expansion = (ShaderExpansion *)NULL;
_vertex_array_shader_context = (CLP(ShaderContext) *)NULL;
+ _texture_binding_shader_expansion = (ShaderExpansion *)NULL;
+ _texture_binding_shader_context = (CLP(ShaderContext) *)NULL;
// Count the max number of lights
GLint max_lights;
@@ -840,20 +842,20 @@ do_clear(const RenderBuffer &buffer) {
int buffer_type = buffer._buffer_type;
GLbitfield mask = 0;
+ set_state_and_transform(RenderState::make_empty(), _external_transform);
+
if (buffer_type & RenderBuffer::T_color) {
GLP(ClearColor)(_color_clear_value[0],
_color_clear_value[1],
_color_clear_value[2],
_color_clear_value[3]);
mask |= GL_COLOR_BUFFER_BIT;
- _target._color_write = AttribSlots::get_defaults()._color_write;
set_draw_buffer(buffer);
}
if (buffer_type & RenderBuffer::T_depth) {
GLP(ClearDepth)(_depth_clear_value);
mask |= GL_DEPTH_BUFFER_BIT;
- _target._depth_write = AttribSlots::get_defaults()._depth_write;
}
if (buffer_type & RenderBuffer::T_stencil) {
@@ -886,20 +888,6 @@ do_clear(const RenderBuffer &buffer) {
GLCAT.spam(false) << ")" << endl;
}
- if (_target._depth_write != _state._depth_write) {
- do_issue_depth_write();
- _state._depth_write = _target._depth_write;
- }
- if ((_target._transparency != _state._transparency)||
- (_target._color_write != _state._color_write)||
- (_target._color_blend != _state._color_blend)) {
- do_issue_blending();
- _state._transparency = _target._transparency;
- _state._color_write = _target._color_write;
- _state._color_blend = _target._color_blend;
- }
- _state_rs = 0;
-
GLP(Clear)(mask);
report_my_gl_errors();
}
@@ -1598,15 +1586,15 @@ draw_triangles(const GeomTriangles *primitive) {
const unsigned char *client_pointer = setup_primitive(primitive);
_glDrawRangeElements(GL_TRIANGLES,
- primitive->get_min_vertex(),
- primitive->get_max_vertex(),
- primitive->get_num_vertices(),
- get_numeric_type(primitive->get_index_type()),
- client_pointer);
+ primitive->get_min_vertex(),
+ primitive->get_max_vertex(),
+ primitive->get_num_vertices(),
+ get_numeric_type(primitive->get_index_type()),
+ client_pointer);
} else {
GLP(DrawArrays)(GL_TRIANGLES,
- primitive->get_first_vertex(),
- primitive->get_num_vertices());
+ primitive->get_first_vertex(),
+ primitive->get_num_vertices());
}
}
@@ -1642,17 +1630,17 @@ draw_tristrips(const GeomTristrips *primitive) {
_vertices_tristrip_pcollector.add_level(primitive->get_num_vertices());
_primitive_batches_tristrip_pcollector.add_level(1);
if (primitive->is_indexed()) {
- const unsigned char *client_pointer = setup_primitive(primitive);
- _glDrawRangeElements(GL_TRIANGLE_STRIP,
- primitive->get_min_vertex(),
- primitive->get_max_vertex(),
- primitive->get_num_vertices(),
- get_numeric_type(primitive->get_index_type()),
- client_pointer);
+ const unsigned char *client_pointer = setup_primitive(primitive);
+ _glDrawRangeElements(GL_TRIANGLE_STRIP,
+ primitive->get_min_vertex(),
+ primitive->get_max_vertex(),
+ primitive->get_num_vertices(),
+ get_numeric_type(primitive->get_index_type()),
+ client_pointer);
} else {
- GLP(DrawArrays)(GL_TRIANGLE_STRIP,
- primitive->get_first_vertex(),
- primitive->get_num_vertices());
+ GLP(DrawArrays)(GL_TRIANGLE_STRIP,
+ primitive->get_first_vertex(),
+ primitive->get_num_vertices());
}
} else {
@@ -1662,32 +1650,32 @@ draw_tristrips(const GeomTristrips *primitive) {
_primitive_batches_tristrip_pcollector.add_level(ends.size());
if (primitive->is_indexed()) {
- const unsigned char *client_pointer = setup_primitive(primitive);
- int index_stride = primitive->get_index_stride();
- GeomVertexReader mins(primitive->get_mins(), 0);
- GeomVertexReader maxs(primitive->get_maxs(), 0);
- nassertv(primitive->get_mins()->get_num_rows() == (int)ends.size() &&
- primitive->get_maxs()->get_num_rows() == (int)ends.size());
-
- unsigned int start = 0;
- for (size_t i = 0; i < ends.size(); i++) {
- _vertices_tristrip_pcollector.add_level(ends[i] - start);
- _glDrawRangeElements(GL_TRIANGLE_STRIP,
- mins.get_data1i(), maxs.get_data1i(),
- ends[i] - start,
- get_numeric_type(primitive->get_index_type()),
- client_pointer + start * index_stride);
- start = ends[i] + 2;
- }
+ const unsigned char *client_pointer = setup_primitive(primitive);
+ int index_stride = primitive->get_index_stride();
+ GeomVertexReader mins(primitive->get_mins(), 0);
+ GeomVertexReader maxs(primitive->get_maxs(), 0);
+ nassertv(primitive->get_mins()->get_num_rows() == (int)ends.size() &&
+ primitive->get_maxs()->get_num_rows() == (int)ends.size());
+
+ unsigned int start = 0;
+ for (size_t i = 0; i < ends.size(); i++) {
+ _vertices_tristrip_pcollector.add_level(ends[i] - start);
+ _glDrawRangeElements(GL_TRIANGLE_STRIP,
+ mins.get_data1i(), maxs.get_data1i(),
+ ends[i] - start,
+ get_numeric_type(primitive->get_index_type()),
+ client_pointer + start * index_stride);
+ start = ends[i] + 2;
+ }
} else {
- unsigned int start = 0;
- int first_vertex = primitive->get_first_vertex();
- for (size_t i = 0; i < ends.size(); i++) {
- _vertices_tristrip_pcollector.add_level(ends[i] - start);
- GLP(DrawArrays)(GL_TRIANGLE_STRIP, first_vertex + start,
- ends[i] - start);
- start = ends[i] + 2;
- }
+ unsigned int start = 0;
+ int first_vertex = primitive->get_first_vertex();
+ for (size_t i = 0; i < ends.size(); i++) {
+ _vertices_tristrip_pcollector.add_level(ends[i] - start);
+ GLP(DrawArrays)(GL_TRIANGLE_STRIP, first_vertex + start,
+ ends[i] - start);
+ start = ends[i] + 2;
+ }
}
}
}
@@ -2453,12 +2441,7 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr,
// for GLP(ReadPixels)() to work
// NOTE: reading the depth buffer is *much* slower than reading the
// color buffer
- _target._texture = AttribSlots::get_defaults()._texture;
- if (_target._texture != _state._texture) {
- do_issue_texture();
- _state._texture = _target._texture;
- }
- _state_rs = 0;
+ set_state_and_transform(RenderState::make_empty(), _external_transform);
int xo, yo, w, h;
dr->get_region_pixels(xo, yo, w, h);
@@ -3086,7 +3069,7 @@ do_issue_blending() {
} else {
if (_target._color_write != _state._color_write) {
if (CLP(color_mask)) {
- unsigned int channels = _target._color_write->get_channels();
+ unsigned int channels = _target._color_write->get_channels();
GLP(ColorMask)((channels & ColorWriteAttrib::C_red) != 0,
(channels & ColorWriteAttrib::C_green) != 0,
(channels & ColorWriteAttrib::C_blue) != 0,
@@ -3576,7 +3559,7 @@ is_at_least_version(int major_version, int minor_version,
return false;
} else if (_gl_version_minor == minor_version) {
if (_gl_version_release < release_version) {
- return false;
+ return false;
}
}
}
@@ -4592,9 +4575,6 @@ set_state_and_transform(const RenderState *target,
// attributes we issue. Impose them now.
_target._texture = _target._texture->filter_to_max(_max_texture_stages);
- bool needs_tex_gen = false;
- bool needs_tex_mat = false;
-
if (_target._alpha_test != _state._alpha_test) {
do_issue_alpha_test();
_state._alpha_test = _target._alpha_test;
@@ -4660,22 +4640,6 @@ set_state_and_transform(const RenderState *target,
_state._shade_model = _target._shade_model;
}
- if (_target._shader != _state._shader) {
- do_issue_shader();
- _state._shader = _target._shader;
- }
-
- if (_target._tex_gen != _state._tex_gen) {
- _state._tex_gen = _target._tex_gen;
- needs_tex_gen = true;
- _state._tex_gen = _target._tex_gen;
- }
-
- if (_target._tex_matrix != _state._tex_matrix) {
- needs_tex_mat = true;
- _state._tex_matrix = _target._tex_matrix;
- }
-
if ((_target._transparency != _state._transparency)||
(_target._color_write != _state._color_write)||
(_target._color_blend != _state._color_blend)) {
@@ -4685,16 +4649,19 @@ set_state_and_transform(const RenderState *target,
_state._color_blend = _target._color_blend;
}
+ if (_target._shader != _state._shader) {
+ do_issue_shader();
+ _state._shader = _target._shader;
+ _state._texture = 0;
+ }
+
if (_target._texture != _state._texture) {
do_issue_texture();
_state._texture = _target._texture;
-
- // Changing the set of texture stages will require us to reissue the
- // texgen and texmat attribs.
- needs_tex_gen = true;
- needs_tex_mat = true;
+ _state._tex_gen = 0;
+ _state._tex_matrix = 0;
}
-
+
if (_target._material != _state._material) {
do_issue_material();
_state._material = _target._material;
@@ -4708,278 +4675,24 @@ set_state_and_transform(const RenderState *target,
// If one of the previously-loaded TexGen modes modified the texture
// matrix, then if either state changed, we have to change both of
// them now.
- if (_tex_gen_modifies_mat && (needs_tex_mat || needs_tex_gen)) {
- needs_tex_mat = true;
- needs_tex_gen = true;
+ if (_tex_gen_modifies_mat) {
+ if ((_target._tex_gen != _state._tex_gen) ||
+ (_target._tex_matrix != _state._tex_matrix)) {
+ _state._tex_matrix = 0;
+ _state._tex_gen = 0;
+ }
}
-
- // Apply the texture matrix, if needed.
- if (needs_tex_mat) {
- int num_stages = _state._texture->get_num_on_stages();
- nassertv(num_stages <= _max_texture_stages);
-
- for (int i = 0; i < num_stages; i++) {
- TextureStage *stage = _state._texture->get_on_stage(i);
- _glActiveTexture(GL_TEXTURE0 + i);
-
- GLP(MatrixMode)(GL_TEXTURE);
- if (_state._tex_matrix->has_stage(stage)) {
- GLP(LoadMatrixf)(_state._tex_matrix->get_mat(stage).get_data());
- } else {
- GLP(LoadIdentity)();
-
- // For some reason, the glLoadIdentity() call doesn't work on
- // my Dell laptop's IBM OpenGL driver, when used in
- // conjunction with glTexGen(), below. But explicitly loading
- // an identity matrix does work. But this buggy-driver
- // workaround might have other performance implications, so I
- // leave it out.
- //GLP(LoadMatrixf)(LMatrix4f::ident_mat().get_data());
- }
- }
- report_my_gl_errors();
+
+ if (_target._tex_matrix != _state._tex_matrix) {
+ do_issue_tex_matrix();
+ _state._tex_matrix = _target._tex_matrix;
}
-
- if (needs_tex_gen) {
- bool force_normal = false;
-
- int num_stages = _state._texture->get_num_on_stages();
- nassertv(num_stages <= _max_texture_stages);
-
- // These are passed in for the four OBJECT_PLANE or EYE_PLANE
- // values; they effectively define an identity matrix that maps
- // the spatial coordinates one-for-one to UV's. If you want a
- // mapping other than identity, use a TexMatrixAttrib (or a
- // TexProjectorEffect).
- static const float s_data[4] = { 1, 0, 0, 0 };
- static const float t_data[4] = { 0, 1, 0, 0 };
- static const float r_data[4] = { 0, 0, 1, 0 };
- static const float q_data[4] = { 0, 0, 0, 1 };
-
- _tex_gen_modifies_mat = false;
-
- bool got_point_sprites = false;
-
- for (int i = 0; i < num_stages; i++) {
- TextureStage *stage = _state._texture->get_on_stage(i);
- _glActiveTexture(GL_TEXTURE0 + i);
- GLP(Disable)(GL_TEXTURE_GEN_S);
- GLP(Disable)(GL_TEXTURE_GEN_T);
- GLP(Disable)(GL_TEXTURE_GEN_R);
- GLP(Disable)(GL_TEXTURE_GEN_Q);
- if (_supports_point_sprite) {
- GLP(TexEnvi)(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_FALSE);
- }
-
- TexGenAttrib::Mode mode = _state._tex_gen->get_mode(stage);
- switch (mode) {
- case TexGenAttrib::M_off:
- case TexGenAttrib::M_light_vector:
- break;
-
- case TexGenAttrib::M_eye_sphere_map:
- GLP(TexGeni)(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
- GLP(TexGeni)(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
- GLP(Enable)(GL_TEXTURE_GEN_S);
- GLP(Enable)(GL_TEXTURE_GEN_T);
- force_normal = true;
- break;
-
- case TexGenAttrib::M_eye_cube_map:
- if (_supports_cube_map) {
- // We need to rotate the normals out of GL's coordinate
- // system and into the user's coordinate system. We do this
- // by composing a transform onto the texture matrix.
- LMatrix4f mat = _inv_cs_transform->get_mat();
- mat.set_row(3, LVecBase3f(0.0f, 0.0f, 0.0f));
- GLP(MatrixMode)(GL_TEXTURE);
- GLP(MultMatrixf)(mat.get_data());
-
- // Now we need to reset the texture matrix next time
- // around to undo this.
- _tex_gen_modifies_mat = true;
-
- GLP(TexGeni)(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
- GLP(TexGeni)(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
- GLP(TexGeni)(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
- GLP(Enable)(GL_TEXTURE_GEN_S);
- GLP(Enable)(GL_TEXTURE_GEN_T);
- GLP(Enable)(GL_TEXTURE_GEN_R);
- force_normal = true;
- }
- break;
-
- case TexGenAttrib::M_world_cube_map:
- if (_supports_cube_map) {
- // We dynamically transform normals from eye space to world
- // space by applying the appropriate rotation transform to
- // the current texture matrix. Unlike M_world_position, we
- // can't achieve this effect by monkeying with the modelview
- // transform, since the current modelview doesn't affect
- // GL_REFLECTION_MAP.
- CPT(TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform);
-
- LMatrix4f mat = camera_transform->get_mat();
- mat.set_row(3, LVecBase3f(0.0f, 0.0f, 0.0f));
- GLP(MatrixMode)(GL_TEXTURE);
- GLP(MultMatrixf)(mat.get_data());
-
- // Now we need to reset the texture matrix next time
- // around to undo this.
- _tex_gen_modifies_mat = true;
-
- GLP(TexGeni)(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
- GLP(TexGeni)(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
- GLP(TexGeni)(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
- GLP(Enable)(GL_TEXTURE_GEN_S);
- GLP(Enable)(GL_TEXTURE_GEN_T);
- GLP(Enable)(GL_TEXTURE_GEN_R);
- force_normal = true;
- }
- break;
-
- case TexGenAttrib::M_eye_normal:
- if (_supports_cube_map) {
- // We need to rotate the normals out of GL's coordinate
- // system and into the user's coordinate system. We do this
- // by composing a transform onto the texture matrix.
- LMatrix4f mat = _inv_cs_transform->get_mat();
- mat.set_row(3, LVecBase3f(0.0f, 0.0f, 0.0f));
- GLP(MatrixMode)(GL_TEXTURE);
- GLP(MultMatrixf)(mat.get_data());
-
- // Now we need to reset the texture matrix next time
- // around to undo this.
- _tex_gen_modifies_mat = true;
-
- GLP(TexGeni)(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
- GLP(TexGeni)(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
- GLP(TexGeni)(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
- GLP(Enable)(GL_TEXTURE_GEN_S);
- GLP(Enable)(GL_TEXTURE_GEN_T);
- GLP(Enable)(GL_TEXTURE_GEN_R);
- force_normal = true;
- }
- break;
-
- case TexGenAttrib::M_world_normal:
- if (_supports_cube_map) {
- // We dynamically transform normals from eye space to world
- // space by applying the appropriate rotation transform to
- // the current texture matrix. Unlike M_world_position, we
- // can't achieve this effect by monkeying with the modelview
- // transform, since the current modelview doesn't affect
- // GL_NORMAL_MAP.
- CPT(TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform);
-
- LMatrix4f mat = camera_transform->get_mat();
- mat.set_row(3, LVecBase3f(0.0f, 0.0f, 0.0f));
- GLP(MatrixMode)(GL_TEXTURE);
- GLP(MultMatrixf)(mat.get_data());
-
- // Now we need to reset the texture matrix next time
- // around to undo this.
- _tex_gen_modifies_mat = true;
-
- GLP(TexGeni)(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
- GLP(TexGeni)(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
- GLP(TexGeni)(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
- GLP(Enable)(GL_TEXTURE_GEN_S);
- GLP(Enable)(GL_TEXTURE_GEN_T);
- GLP(Enable)(GL_TEXTURE_GEN_R);
- force_normal = true;
- }
- break;
-
- case TexGenAttrib::M_eye_position:
- // To represent eye position correctly, we need to temporarily
- // load the coordinate-system transform.
- GLP(MatrixMode)(GL_MODELVIEW);
- GLP(PushMatrix)();
- GLP(LoadMatrixf)(_cs_transform->get_mat().get_data());
-
- GLP(TexGeni)(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
- GLP(TexGeni)(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
- GLP(TexGeni)(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
- GLP(TexGeni)(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
-
- GLP(TexGenfv)(GL_S, GL_EYE_PLANE, s_data);
- GLP(TexGenfv)(GL_T, GL_EYE_PLANE, t_data);
- GLP(TexGenfv)(GL_R, GL_EYE_PLANE, r_data);
- GLP(TexGenfv)(GL_Q, GL_EYE_PLANE, q_data);
-
- GLP(Enable)(GL_TEXTURE_GEN_S);
- GLP(Enable)(GL_TEXTURE_GEN_T);
- GLP(Enable)(GL_TEXTURE_GEN_R);
- GLP(Enable)(GL_TEXTURE_GEN_Q);
-
- GLP(MatrixMode)(GL_MODELVIEW);
- GLP(PopMatrix)();
- break;
-
- case TexGenAttrib::M_world_position:
- // We achieve world position coordinates by using the eye
- // position mode, and loading the transform of the root
- // node--thus putting the "eye" at the root.
- {
- GLP(MatrixMode)(GL_MODELVIEW);
- GLP(PushMatrix)();
- CPT(TransformState) root_transform = _cs_transform->compose(_scene_setup->get_world_transform());
- GLP(LoadMatrixf)(root_transform->get_mat().get_data());
- GLP(TexGeni)(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
- GLP(TexGeni)(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
- GLP(TexGeni)(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
- GLP(TexGeni)(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
-
- GLP(TexGenfv)(GL_S, GL_EYE_PLANE, s_data);
- GLP(TexGenfv)(GL_T, GL_EYE_PLANE, t_data);
- GLP(TexGenfv)(GL_R, GL_EYE_PLANE, r_data);
- GLP(TexGenfv)(GL_Q, GL_EYE_PLANE, q_data);
-
- GLP(Enable)(GL_TEXTURE_GEN_S);
- GLP(Enable)(GL_TEXTURE_GEN_T);
- GLP(Enable)(GL_TEXTURE_GEN_R);
- GLP(Enable)(GL_TEXTURE_GEN_Q);
-
- GLP(MatrixMode)(GL_MODELVIEW);
- GLP(PopMatrix)();
- }
- break;
-
- case TexGenAttrib::M_point_sprite:
- nassertv(_supports_point_sprite);
- GLP(TexEnvi)(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE);
- got_point_sprites = true;
- break;
-
- case TexGenAttrib::M_unused:
- break;
- }
- }
-
- if (got_point_sprites != _tex_gen_point_sprite) {
- _tex_gen_point_sprite = got_point_sprites;
- if (_tex_gen_point_sprite) {
- GLP(Enable)(GL_POINT_SPRITE_ARB);
- } else {
- GLP(Disable)(GL_POINT_SPRITE_ARB);
- }
- }
-
- // Certain texgen modes (sphere_map, cube_map) require forcing the
- // normal to be sent to the GL while the texgen mode is in effect.
- if (force_normal != _texgen_forced_normal) {
- if (force_normal) {
- force_normals();
- } else {
- undo_force_normals();
- }
- _texgen_forced_normal = force_normal;
- }
-
- report_my_gl_errors();
+
+ if (_target._tex_gen != _state._tex_gen) {
+ do_issue_tex_gen();
+ _state._tex_gen = _target._tex_gen;
}
-
+
_state_rs = _target_rs;
}
@@ -5030,19 +4743,47 @@ do_auto_rescale_normal() {
////////////////////////////////////////////////////////////////////
// Function: GLGraphicsStateGuardian::do_issue_texture
// Access: Protected, Virtual
-// Description: This is called by finish_modify_state() when the
-// texture state has changed.
+// Description: This is called by set_state_and_transform() when
+// the texture state has changed.
////////////////////////////////////////////////////////////////////
void CLP(GraphicsStateGuardian)::
do_issue_texture() {
DO_PSTATS_STUFF(_texture_state_pcollector.add_level(1));
+
+ if (_texture_binding_shader_context==0) {
+ if (_current_shader_context==0) {
+ update_standard_texture_bindings();
+ } else {
+ disable_standard_texture_bindings();
+ _current_shader_context->update_shader_texture_bindings(NULL,this);
+ }
+ } else {
+ if (_current_shader_context==0) {
+ _texture_binding_shader_context->disable_shader_texture_bindings(this);
+ update_standard_texture_bindings();
+ } else {
+ _current_shader_context->
+ update_shader_texture_bindings(_texture_binding_shader_context,this);
+ }
+ }
+ _texture_binding_shader_expansion = _current_shader_expansion;
+ _texture_binding_shader_context = _current_shader_context;
+}
+////////////////////////////////////////////////////////////////////
+// Function: GLGraphicsStateGuardian::update_standard_texture_bindings
+// Access: Private
+// Description:
+////////////////////////////////////////////////////////////////////
+void CLP(GraphicsStateGuardian)::
+update_standard_texture_bindings()
+{
int num_stages = _target._texture->get_num_on_stages();
int num_old_stages = _max_texture_stages;
if (_state._texture != (TextureAttrib *)NULL) {
num_old_stages = _state._texture->get_num_on_stages();
}
-
+
nassertv(num_stages <= _max_texture_stages &&
num_old_stages <= _max_texture_stages);
@@ -5057,7 +4798,7 @@ do_issue_texture() {
nassertv(texture != (Texture *)NULL);
if (i >= num_old_stages ||
- _state._texture == (TextureAttrib *)NULL ||
+ _state._texture == (TextureAttrib *)NULL ||
stage != _state._texture->get_on_stage(i) ||
texture != _state._texture->get_on_texture(stage) ||
stage->involves_color_scale()) {
@@ -5202,7 +4943,7 @@ do_issue_texture() {
}
GLP(MatrixMode)(GL_TEXTURE);
- if (_state._tex_matrix->has_stage(stage)) {
+ if (_target._tex_matrix->has_stage(stage)) {
GLP(LoadMatrixf)(_state._tex_matrix->get_mat(stage).get_data());
} else {
GLP(LoadIdentity)();
@@ -5236,6 +4977,313 @@ do_issue_texture() {
report_my_gl_errors();
}
+
+////////////////////////////////////////////////////////////////////
+// Function: GLGraphicsStateGuardian::disable_standard_texture_bindings
+// Access: Private
+// Description:
+////////////////////////////////////////////////////////////////////
+void CLP(GraphicsStateGuardian)::
+disable_standard_texture_bindings() {
+ int num_old_stages = _max_texture_stages;
+ if (_state._texture != (TextureAttrib *)NULL) {
+ num_old_stages = _state._texture->get_num_on_stages();
+ }
+
+ // Disable the texture stages that are no longer used.
+ for (int i = 0; i < num_old_stages; i++) {
+ _glActiveTexture(GL_TEXTURE0 + i);
+ GLP(Disable)(GL_TEXTURE_1D);
+ GLP(Disable)(GL_TEXTURE_2D);
+ if (_supports_3d_texture) {
+ GLP(Disable)(GL_TEXTURE_3D);
+ }
+ if (_supports_cube_map) {
+ GLP(Disable)(GL_TEXTURE_CUBE_MAP);
+ }
+ }
+
+ report_my_gl_errors();
+}
+
+////////////////////////////////////////////////////////////////////
+// Function: GLGraphicsStateGuardian::do_issue_tex_matrix
+// Access: Protected
+// Description:
+////////////////////////////////////////////////////////////////////
+void CLP(GraphicsStateGuardian)::
+do_issue_tex_matrix() {
+ int num_stages = _target._texture->get_num_on_stages();
+ nassertv(num_stages <= _max_texture_stages);
+
+ for (int i = 0; i < num_stages; i++) {
+ TextureStage *stage = _target._texture->get_on_stage(i);
+ _glActiveTexture(GL_TEXTURE0 + i);
+
+ GLP(MatrixMode)(GL_TEXTURE);
+ if (_target._tex_matrix->has_stage(stage)) {
+ GLP(LoadMatrixf)(_target._tex_matrix->get_mat(stage).get_data());
+ } else {
+ GLP(LoadIdentity)();
+
+ // For some reason, the glLoadIdentity() call doesn't work on
+ // my Dell laptop's IBM OpenGL driver, when used in
+ // conjunction with glTexGen(), below. But explicitly loading
+ // an identity matrix does work. But this buggy-driver
+ // workaround might have other performance implications, so I
+ // leave it out.
+ //GLP(LoadMatrixf)(LMatrix4f::ident_mat().get_data());
+ }
+ }
+ report_my_gl_errors();
+}
+
+////////////////////////////////////////////////////////////////////
+// Function: GLGraphicsStateGuardian::do_issue_tex_gen
+// Access: Protected
+// Description:
+////////////////////////////////////////////////////////////////////
+void CLP(GraphicsStateGuardian)::
+do_issue_tex_gen() {
+ bool force_normal = false;
+
+ int num_stages = _target._texture->get_num_on_stages();
+ nassertv(num_stages <= _max_texture_stages);
+
+ // These are passed in for the four OBJECT_PLANE or EYE_PLANE
+ // values; they effectively define an identity matrix that maps
+ // the spatial coordinates one-for-one to UV's. If you want a
+ // mapping other than identity, use a TexMatrixAttrib (or a
+ // TexProjectorEffect).
+ static const float s_data[4] = { 1, 0, 0, 0 };
+ static const float t_data[4] = { 0, 1, 0, 0 };
+ static const float r_data[4] = { 0, 0, 1, 0 };
+ static const float q_data[4] = { 0, 0, 0, 1 };
+
+ _tex_gen_modifies_mat = false;
+
+ bool got_point_sprites = false;
+
+ for (int i = 0; i < num_stages; i++) {
+ TextureStage *stage = _target._texture->get_on_stage(i);
+ _glActiveTexture(GL_TEXTURE0 + i);
+ GLP(Disable)(GL_TEXTURE_GEN_S);
+ GLP(Disable)(GL_TEXTURE_GEN_T);
+ GLP(Disable)(GL_TEXTURE_GEN_R);
+ GLP(Disable)(GL_TEXTURE_GEN_Q);
+ if (_supports_point_sprite) {
+ GLP(TexEnvi)(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_FALSE);
+ }
+
+ TexGenAttrib::Mode mode = _target._tex_gen->get_mode(stage);
+ switch (mode) {
+ case TexGenAttrib::M_off:
+ case TexGenAttrib::M_light_vector:
+ break;
+
+ case TexGenAttrib::M_eye_sphere_map:
+ GLP(TexGeni)(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
+ GLP(TexGeni)(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
+ GLP(Enable)(GL_TEXTURE_GEN_S);
+ GLP(Enable)(GL_TEXTURE_GEN_T);
+ force_normal = true;
+ break;
+
+ case TexGenAttrib::M_eye_cube_map:
+ if (_supports_cube_map) {
+ // We need to rotate the normals out of GL's coordinate
+ // system and into the user's coordinate system. We do this
+ // by composing a transform onto the texture matrix.
+ LMatrix4f mat = _inv_cs_transform->get_mat();
+ mat.set_row(3, LVecBase3f(0.0f, 0.0f, 0.0f));
+ GLP(MatrixMode)(GL_TEXTURE);
+ GLP(MultMatrixf)(mat.get_data());
+
+ // Now we need to reset the texture matrix next time
+ // around to undo this.
+ _tex_gen_modifies_mat = true;
+
+ GLP(TexGeni)(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
+ GLP(TexGeni)(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
+ GLP(TexGeni)(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
+ GLP(Enable)(GL_TEXTURE_GEN_S);
+ GLP(Enable)(GL_TEXTURE_GEN_T);
+ GLP(Enable)(GL_TEXTURE_GEN_R);
+ force_normal = true;
+ }
+ break;
+
+ case TexGenAttrib::M_world_cube_map:
+ if (_supports_cube_map) {
+ // We dynamically transform normals from eye space to world
+ // space by applying the appropriate rotation transform to
+ // the current texture matrix. Unlike M_world_position, we
+ // can't achieve this effect by monkeying with the modelview
+ // transform, since the current modelview doesn't affect
+ // GL_REFLECTION_MAP.
+ CPT(TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform);
+
+ LMatrix4f mat = camera_transform->get_mat();
+ mat.set_row(3, LVecBase3f(0.0f, 0.0f, 0.0f));
+ GLP(MatrixMode)(GL_TEXTURE);
+ GLP(MultMatrixf)(mat.get_data());
+
+ // Now we need to reset the texture matrix next time
+ // around to undo this.
+ _tex_gen_modifies_mat = true;
+
+ GLP(TexGeni)(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
+ GLP(TexGeni)(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
+ GLP(TexGeni)(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
+ GLP(Enable)(GL_TEXTURE_GEN_S);
+ GLP(Enable)(GL_TEXTURE_GEN_T);
+ GLP(Enable)(GL_TEXTURE_GEN_R);
+ force_normal = true;
+ }
+ break;
+
+ case TexGenAttrib::M_eye_normal:
+ if (_supports_cube_map) {
+ // We need to rotate the normals out of GL's coordinate
+ // system and into the user's coordinate system. We do this
+ // by composing a transform onto the texture matrix.
+ LMatrix4f mat = _inv_cs_transform->get_mat();
+ mat.set_row(3, LVecBase3f(0.0f, 0.0f, 0.0f));
+ GLP(MatrixMode)(GL_TEXTURE);
+ GLP(MultMatrixf)(mat.get_data());
+
+ // Now we need to reset the texture matrix next time
+ // around to undo this.
+ _tex_gen_modifies_mat = true;
+
+ GLP(TexGeni)(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
+ GLP(TexGeni)(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
+ GLP(TexGeni)(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
+ GLP(Enable)(GL_TEXTURE_GEN_S);
+ GLP(Enable)(GL_TEXTURE_GEN_T);
+ GLP(Enable)(GL_TEXTURE_GEN_R);
+ force_normal = true;
+ }
+ break;
+
+ case TexGenAttrib::M_world_normal:
+ if (_supports_cube_map) {
+ // We dynamically transform normals from eye space to world
+ // space by applying the appropriate rotation transform to
+ // the current texture matrix. Unlike M_world_position, we
+ // can't achieve this effect by monkeying with the modelview
+ // transform, since the current modelview doesn't affect
+ // GL_NORMAL_MAP.
+ CPT(TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform);
+
+ LMatrix4f mat = camera_transform->get_mat();
+ mat.set_row(3, LVecBase3f(0.0f, 0.0f, 0.0f));
+ GLP(MatrixMode)(GL_TEXTURE);
+ GLP(MultMatrixf)(mat.get_data());
+
+ // Now we need to reset the texture matrix next time
+ // around to undo this.
+ _tex_gen_modifies_mat = true;
+
+ GLP(TexGeni)(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
+ GLP(TexGeni)(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
+ GLP(TexGeni)(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
+ GLP(Enable)(GL_TEXTURE_GEN_S);
+ GLP(Enable)(GL_TEXTURE_GEN_T);
+ GLP(Enable)(GL_TEXTURE_GEN_R);
+ force_normal = true;
+ }
+ break;
+
+ case TexGenAttrib::M_eye_position:
+ // To represent eye position correctly, we need to temporarily
+ // load the coordinate-system transform.
+ GLP(MatrixMode)(GL_MODELVIEW);
+ GLP(PushMatrix)();
+ GLP(LoadMatrixf)(_cs_transform->get_mat().get_data());
+
+ GLP(TexGeni)(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+ GLP(TexGeni)(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+ GLP(TexGeni)(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+ GLP(TexGeni)(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+
+ GLP(TexGenfv)(GL_S, GL_EYE_PLANE, s_data);
+ GLP(TexGenfv)(GL_T, GL_EYE_PLANE, t_data);
+ GLP(TexGenfv)(GL_R, GL_EYE_PLANE, r_data);
+ GLP(TexGenfv)(GL_Q, GL_EYE_PLANE, q_data);
+
+ GLP(Enable)(GL_TEXTURE_GEN_S);
+ GLP(Enable)(GL_TEXTURE_GEN_T);
+ GLP(Enable)(GL_TEXTURE_GEN_R);
+ GLP(Enable)(GL_TEXTURE_GEN_Q);
+
+ GLP(MatrixMode)(GL_MODELVIEW);
+ GLP(PopMatrix)();
+ break;
+
+ case TexGenAttrib::M_world_position:
+ // We achieve world position coordinates by using the eye
+ // position mode, and loading the transform of the root
+ // node--thus putting the "eye" at the root.
+ {
+ GLP(MatrixMode)(GL_MODELVIEW);
+ GLP(PushMatrix)();
+ CPT(TransformState) root_transform = _cs_transform->compose(_scene_setup->get_world_transform());
+ GLP(LoadMatrixf)(root_transform->get_mat().get_data());
+ GLP(TexGeni)(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+ GLP(TexGeni)(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+ GLP(TexGeni)(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+ GLP(TexGeni)(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+
+ GLP(TexGenfv)(GL_S, GL_EYE_PLANE, s_data);
+ GLP(TexGenfv)(GL_T, GL_EYE_PLANE, t_data);
+ GLP(TexGenfv)(GL_R, GL_EYE_PLANE, r_data);
+ GLP(TexGenfv)(GL_Q, GL_EYE_PLANE, q_data);
+
+ GLP(Enable)(GL_TEXTURE_GEN_S);
+ GLP(Enable)(GL_TEXTURE_GEN_T);
+ GLP(Enable)(GL_TEXTURE_GEN_R);
+ GLP(Enable)(GL_TEXTURE_GEN_Q);
+
+ GLP(MatrixMode)(GL_MODELVIEW);
+ GLP(PopMatrix)();
+ }
+ break;
+
+ case TexGenAttrib::M_point_sprite:
+ nassertv(_supports_point_sprite);
+ GLP(TexEnvi)(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE);
+ got_point_sprites = true;
+ break;
+
+ case TexGenAttrib::M_unused:
+ break;
+ }
+ }
+
+ if (got_point_sprites != _tex_gen_point_sprite) {
+ _tex_gen_point_sprite = got_point_sprites;
+ if (_tex_gen_point_sprite) {
+ GLP(Enable)(GL_POINT_SPRITE_ARB);
+ } else {
+ GLP(Disable)(GL_POINT_SPRITE_ARB);
+ }
+ }
+
+ // Certain texgen modes (sphere_map, cube_map) require forcing the
+ // normal to be sent to the GL while the texgen mode is in effect.
+ if (force_normal != _texgen_forced_normal) {
+ if (force_normal) {
+ force_normals();
+ } else {
+ undo_force_normals();
+ }
+ _texgen_forced_normal = force_normal;
+ }
+
+ report_my_gl_errors();
+}
+
////////////////////////////////////////////////////////////////////
// Function: GLGraphicsStateGuardian::specify_texture
// Access: Protected
diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h
index e9b9f58f6f..f8b34038ea 100644
--- a/panda/src/glstuff/glGraphicsStateGuardian_src.h
+++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h
@@ -177,6 +177,8 @@ protected:
void do_issue_material();
void do_issue_texture();
void do_issue_blending();
+ void do_issue_tex_gen();
+ void do_issue_tex_matrix();
static bool report_errors_loop(int line, const char *source_file,
GLenum error_code, int &error_count);
@@ -249,6 +251,8 @@ protected:
void disable_standard_vertex_arrays();
void update_standard_vertex_arrays();
+ void disable_standard_texture_bindings();
+ void update_standard_texture_bindings();
void do_auto_rescale_normal();
void specify_texture(Texture *tex);
@@ -310,6 +314,8 @@ protected:
CLP(ShaderContext) *_current_shader_context;
PT(ShaderExpansion) _vertex_array_shader_expansion;
CLP(ShaderContext) *_vertex_array_shader_context;
+ PT(ShaderExpansion) _texture_binding_shader_expansion;
+ CLP(ShaderContext) *_texture_binding_shader_context;
CPT(DisplayRegion) _actual_display_region;
diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx
index 33062d63a2..7b985281de 100755
--- a/panda/src/glstuff/glShaderContext_src.cxx
+++ b/panda/src/glstuff/glShaderContext_src.cxx
@@ -307,6 +307,84 @@ update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg)
#endif // HAVE_CGGL
}
+////////////////////////////////////////////////////////////////////
+// Function: GLShaderContext::disable_shader_texture_bindings
+// Access: Public
+// Description: Disable all the texture bindings used by this shader.
+////////////////////////////////////////////////////////////////////
+void CLP(ShaderContext)::
+disable_shader_texture_bindings(GSG *gsg)
+{
+#ifdef HAVE_CGGL
+ if (_cg_context) {
+ for (int i=0; i<(int)_cg_texbind.size(); i++) {
+ int texunit = cgGetParameterResourceIndex(_cg_texbind[i].parameter);
+ gsg->_glActiveTexture(GL_TEXTURE0 + texunit);
+ GLP(Disable)(GL_TEXTURE_1D);
+ GLP(Disable)(GL_TEXTURE_2D);
+ if (gsg->_supports_3d_texture) {
+ GLP(Disable)(GL_TEXTURE_3D);
+ }
+ if (gsg->_supports_cube_map) {
+ GLP(Disable)(GL_TEXTURE_CUBE_MAP);
+ }
+ // This is probably faster - but maybe not as safe?
+ // cgGLDisableTextureParameter(_cg_texbind[i].parameter);
+ }
+ }
+#endif
+}
+
+////////////////////////////////////////////////////////////////////
+// Function: GLShaderContext::update_shader_texture_bindings
+// Access: Public
+// Description: Disables all texture bindings used by the previous
+// shader, then enables all the texture bindings needed
+// by this shader. Extracts the relevant vertex array
+// data from the gsg.
+// The current implementation is inefficient, because
+// it may unnecessarily disable textures then immediately
+// reenable them. We may optimize this someday.
+////////////////////////////////////////////////////////////////////
+void CLP(ShaderContext)::
+update_shader_texture_bindings(CLP(ShaderContext) *prev, GSG *gsg)
+{
+ if (prev) prev->disable_shader_texture_bindings(gsg);
+#ifdef HAVE_CGGL
+ if (_cg_context) {
+ for (int i=0; i<(int)_cg_texbind.size(); i++) {
+ Texture *tex = 0;
+ InternalName *id = _cg_texbind[i].name;
+ if (id != 0) {
+ const ShaderInput *input = gsg->_target._shader->get_input(id);
+ tex = input->get_texture();
+ } else {
+ TextureStage *stage = gsg->_target._texture->get_on_stage(_cg_texbind[i].stage);
+ tex = gsg->_target._texture->get_on_texture(stage);
+ }
+ if ((tex == 0) || (tex->get_texture_type() != _cg_texbind[i].desiredtype)) {
+ continue;
+ }
+ TextureContext *tc = tex->prepare_now(gsg->_prepared_objects, gsg);
+ if (tc == (TextureContext*)NULL) {
+ continue;
+ }
+ int texunit = cgGetParameterResourceIndex(_cg_texbind[i].parameter);
+ gsg->_glActiveTexture(GL_TEXTURE0 + texunit);
+
+ GLenum target = gsg->get_texture_target(tex->get_texture_type());
+ if (target == GL_NONE) {
+ // Unsupported texture mode.
+ continue;
+ }
+ GLP(Enable)(target);
+
+ gsg->apply_texture(tc);
+ }
+ }
+#endif
+}
+
#ifdef HAVE_CGGL
////////////////////////////////////////////////////////////////////
// Function: GLShaderContext::bind_cg_transform
@@ -321,6 +399,8 @@ bind_cg_transform(const ShaderTransBind &stb, GSG *gsg)
if (stb.src_name == InternalName::get_camera()) {
src = TransformState::make_identity();
+ } else if (stb.src_name == InternalName::get_view()) {
+ src = gsg->_cs_transform;
} else if (stb.src_name == InternalName::get_model()) {
src = gsg->get_transform();
} else if (stb.src_name == InternalName::get_world()) {
@@ -337,6 +417,8 @@ bind_cg_transform(const ShaderTransBind &stb, GSG *gsg)
if (stb.rel_name == InternalName::get_camera()) {
rel = TransformState::make_identity();
+ } else if (stb.src_name == InternalName::get_view()) {
+ rel = gsg->_cs_transform;
} else if (stb.rel_name == InternalName::get_model()) {
rel = gsg->get_transform();
} else if (stb.rel_name == InternalName::get_world()) {
@@ -498,7 +580,10 @@ bool CLP(ShaderContext)::
errchk_cg_parameter_sampler(CGparameter p)
{
CGtype t = cgGetParameterType(p);
- if (t != CG_SAMPLER2D) {
+ if ((t!=CG_SAMPLER1D)&&
+ (t!=CG_SAMPLER2D)&&
+ (t!=CG_SAMPLER3D)&&
+ (t!=CG_SAMPLERCUBE)) {
errchk_cg_output(p, "parameter should have a 'sampler' type");
return false;
}
@@ -744,8 +829,21 @@ compile_cg_parameter(CGparameter p)
(!errchk_cg_parameter_variance(p, CG_UNIFORM)) ||
(!errchk_cg_parameter_sampler(p)))
return false;
- // IMPLEMENT ME
- return true; // Cg handles this automatically.
+ ShaderTexBind bind;
+ bind.parameter = p;
+ bind.name = 0;
+ bind.stage = atoi(pieces[1].c_str());
+ switch (cgGetParameterType(p)) {
+ case CG_SAMPLER1D: bind.desiredtype = Texture::TT_1d_texture; break;
+ case CG_SAMPLER2D: bind.desiredtype = Texture::TT_2d_texture; break;
+ case CG_SAMPLER3D: bind.desiredtype = Texture::TT_3d_texture; break;
+ case CG_SAMPLERCUBE: bind.desiredtype = Texture::TT_cube_map; break;
+ default:
+ errchk_cg_output(p, "Invalid type for a tex-parameter");
+ return false;
+ }
+ _cg_texbind.push_back(bind);
+ return true;
}
if (pieces[0] == "k") {
@@ -753,14 +851,53 @@ compile_cg_parameter(CGparameter p)
(!errchk_cg_parameter_direction(p, CG_IN)) ||
(!errchk_cg_parameter_variance(p, CG_UNIFORM)))
return false;
- ShaderArgBind bind;
- bind.parameter = p;
- bind.name = InternalName::make(pieces[1]);
switch (cgGetParameterType(p)) {
- case CG_FLOAT4: _cg_fbind.push_back(bind); break;
- case CG_SAMPLER2D: _cg_tbind2d.push_back(bind); break;
- case CG_SAMPLER3D: _cg_tbind3d.push_back(bind); break;
- case CG_FLOAT4x4: _cg_npbind.push_back(bind); break;
+ case CG_FLOAT4: {
+ ShaderArgBind bind;
+ bind.parameter = p;
+ bind.name = InternalName::make(pieces[1]);
+ _cg_fbind.push_back(bind);
+ break;
+ }
+ case CG_FLOAT4x4: {
+ ShaderArgBind bind;
+ bind.parameter = p;
+ bind.name = InternalName::make(pieces[1]);
+ _cg_npbind.push_back(bind);
+ break;
+ }
+ case CG_SAMPLER1D: {
+ ShaderTexBind bind;
+ bind.parameter = p;
+ bind.name = InternalName::make(pieces[1]);
+ bind.desiredtype=Texture::TT_1d_texture;
+ _cg_texbind.push_back(bind);
+ break;
+ }
+ case CG_SAMPLER2D: {
+ ShaderTexBind bind;
+ bind.parameter = p;
+ bind.name = InternalName::make(pieces[1]);
+ bind.desiredtype=Texture::TT_2d_texture;
+ _cg_texbind.push_back(bind);
+ break;
+ }
+ case CG_SAMPLER3D: {
+ ShaderTexBind bind;
+ bind.parameter = p;
+ bind.name = InternalName::make(pieces[1]);
+ bind.desiredtype=Texture::TT_3d_texture;
+ _cg_texbind.push_back(bind);
+ break;
+ }
+ case CG_SAMPLERCUBE: {
+ ShaderTexBind bind;
+ bind.parameter = p;
+ bind.name = InternalName::make(pieces[1]);
+ bind.desiredtype = Texture::TT_cube_map;
+ _cg_texbind.push_back(bind);
+ break;
+ }
default:
errchk_cg_output(p, "Invalid type for a k-parameter");
return false;
diff --git a/panda/src/glstuff/glShaderContext_src.h b/panda/src/glstuff/glShaderContext_src.h
index c96e70a675..4c88cdba08 100755
--- a/panda/src/glstuff/glShaderContext_src.h
+++ b/panda/src/glstuff/glShaderContext_src.h
@@ -45,6 +45,8 @@ public:
void issue_transform(GSG *gsg);
void disable_shader_vertex_arrays(GSG *gsg);
void update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg);
+ void disable_shader_texture_bindings(GSG *gsg);
+ void update_shader_texture_bindings(CLP(ShaderContext) *prev, GSG *gsg);
private:
@@ -58,6 +60,12 @@ private:
CGparameter parameter;
PT(InternalName) name;
};
+ struct ShaderTexBind {
+ CGparameter parameter;
+ PT(InternalName) name;
+ int stage;
+ int desiredtype;
+ };
struct ShaderTransBind {
CGparameter parameter;
PT(InternalName) src_name;
@@ -76,10 +84,9 @@ private:
// These arrays contain lists of "bindings." They
// tell us how to fill the shader's input parameters.
vector _cg_autobind;
- vector _cg_tbind2d;
- vector _cg_tbind3d;
vector _cg_fbind;
vector _cg_npbind;
+ vector _cg_texbind;
vector _cg_transform_bind;
vector _cg_parameter_bind;
vector _cg_varying;
diff --git a/panda/src/gobj/internalName.I b/panda/src/gobj/internalName.I
index 76b1e7e3d6..d37991adb2 100644
--- a/panda/src/gobj/internalName.I
+++ b/panda/src/gobj/internalName.I
@@ -417,6 +417,20 @@ get_model() {
return _model;
}
+////////////////////////////////////////////////////////////////////
+// Function: InternalName::get_view
+// Access: Published, Static
+// Description: Returns the standard InternalName "view". This is
+// used as a keyword in the shader subsystem.
+////////////////////////////////////////////////////////////////////
+INLINE PT(InternalName) InternalName::
+get_view() {
+ if (_view == (InternalName *)NULL) {
+ _view = InternalName::make("view");
+ }
+ return _view;
+}
+
////////////////////////////////////////////////////////////////////
// Function: InternalName::output operator
// Access: Public
diff --git a/panda/src/gobj/internalName.cxx b/panda/src/gobj/internalName.cxx
index 6d7cab6346..31e8c8f28c 100644
--- a/panda/src/gobj/internalName.cxx
+++ b/panda/src/gobj/internalName.cxx
@@ -42,6 +42,7 @@ PT(InternalName) InternalName::_index;
PT(InternalName) InternalName::_world;
PT(InternalName) InternalName::_camera;
PT(InternalName) InternalName::_model;
+PT(InternalName) InternalName::_view;
TypeHandle InternalName::_type_handle;
TypeHandle InternalName::_texcoord_type_handle;
diff --git a/panda/src/gobj/internalName.h b/panda/src/gobj/internalName.h
index 2d62289319..c60f4ac145 100644
--- a/panda/src/gobj/internalName.h
+++ b/panda/src/gobj/internalName.h
@@ -84,6 +84,7 @@ PUBLISHED:
INLINE static PT(InternalName) get_world();
INLINE static PT(InternalName) get_camera();
INLINE static PT(InternalName) get_model();
+ INLINE static PT(InternalName) get_view();
private:
PT(InternalName) _parent;
@@ -111,6 +112,7 @@ private:
static PT(InternalName) _world;
static PT(InternalName) _camera;
static PT(InternalName) _model;
+ static PT(InternalName) _view;
public:
// Datagram stuff