mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 02:15:43 -04:00
Added texture handling in shader code
This commit is contained in:
parent
be64a3bd8a
commit
0c7e721e79
@ -17,8 +17,8 @@
|
|||||||
ConfigurationType="0">
|
ConfigurationType="0">
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCNMakeTool"
|
Name="VCNMakeTool"
|
||||||
BuildCommandLine="cd .. & makepanda\makepanda --everything --installer"
|
BuildCommandLine="cd .. & makepanda\makepanda --everything"
|
||||||
Output="..\built\bin\flt2egg.exe"/>
|
Output="..\built\python\python.exe"/>
|
||||||
</Configuration>
|
</Configuration>
|
||||||
</Configurations>
|
</Configurations>
|
||||||
<References>
|
<References>
|
||||||
|
@ -757,6 +757,8 @@ reset() {
|
|||||||
_current_shader_context = (CLP(ShaderContext) *)NULL;
|
_current_shader_context = (CLP(ShaderContext) *)NULL;
|
||||||
_vertex_array_shader_expansion = (ShaderExpansion *)NULL;
|
_vertex_array_shader_expansion = (ShaderExpansion *)NULL;
|
||||||
_vertex_array_shader_context = (CLP(ShaderContext) *)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
|
// Count the max number of lights
|
||||||
GLint max_lights;
|
GLint max_lights;
|
||||||
@ -840,20 +842,20 @@ do_clear(const RenderBuffer &buffer) {
|
|||||||
int buffer_type = buffer._buffer_type;
|
int buffer_type = buffer._buffer_type;
|
||||||
GLbitfield mask = 0;
|
GLbitfield mask = 0;
|
||||||
|
|
||||||
|
set_state_and_transform(RenderState::make_empty(), _external_transform);
|
||||||
|
|
||||||
if (buffer_type & RenderBuffer::T_color) {
|
if (buffer_type & RenderBuffer::T_color) {
|
||||||
GLP(ClearColor)(_color_clear_value[0],
|
GLP(ClearColor)(_color_clear_value[0],
|
||||||
_color_clear_value[1],
|
_color_clear_value[1],
|
||||||
_color_clear_value[2],
|
_color_clear_value[2],
|
||||||
_color_clear_value[3]);
|
_color_clear_value[3]);
|
||||||
mask |= GL_COLOR_BUFFER_BIT;
|
mask |= GL_COLOR_BUFFER_BIT;
|
||||||
_target._color_write = AttribSlots::get_defaults()._color_write;
|
|
||||||
set_draw_buffer(buffer);
|
set_draw_buffer(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buffer_type & RenderBuffer::T_depth) {
|
if (buffer_type & RenderBuffer::T_depth) {
|
||||||
GLP(ClearDepth)(_depth_clear_value);
|
GLP(ClearDepth)(_depth_clear_value);
|
||||||
mask |= GL_DEPTH_BUFFER_BIT;
|
mask |= GL_DEPTH_BUFFER_BIT;
|
||||||
_target._depth_write = AttribSlots::get_defaults()._depth_write;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buffer_type & RenderBuffer::T_stencil) {
|
if (buffer_type & RenderBuffer::T_stencil) {
|
||||||
@ -886,20 +888,6 @@ do_clear(const RenderBuffer &buffer) {
|
|||||||
GLCAT.spam(false) << ")" << endl;
|
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);
|
GLP(Clear)(mask);
|
||||||
report_my_gl_errors();
|
report_my_gl_errors();
|
||||||
}
|
}
|
||||||
@ -2453,12 +2441,7 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr,
|
|||||||
// for GLP(ReadPixels)() to work
|
// for GLP(ReadPixels)() to work
|
||||||
// NOTE: reading the depth buffer is *much* slower than reading the
|
// NOTE: reading the depth buffer is *much* slower than reading the
|
||||||
// color buffer
|
// color buffer
|
||||||
_target._texture = AttribSlots::get_defaults()._texture;
|
set_state_and_transform(RenderState::make_empty(), _external_transform);
|
||||||
if (_target._texture != _state._texture) {
|
|
||||||
do_issue_texture();
|
|
||||||
_state._texture = _target._texture;
|
|
||||||
}
|
|
||||||
_state_rs = 0;
|
|
||||||
|
|
||||||
int xo, yo, w, h;
|
int xo, yo, w, h;
|
||||||
dr->get_region_pixels(xo, yo, w, h);
|
dr->get_region_pixels(xo, yo, w, h);
|
||||||
@ -4592,9 +4575,6 @@ set_state_and_transform(const RenderState *target,
|
|||||||
// attributes we issue. Impose them now.
|
// attributes we issue. Impose them now.
|
||||||
_target._texture = _target._texture->filter_to_max(_max_texture_stages);
|
_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) {
|
if (_target._alpha_test != _state._alpha_test) {
|
||||||
do_issue_alpha_test();
|
do_issue_alpha_test();
|
||||||
_state._alpha_test = _target._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;
|
_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)||
|
if ((_target._transparency != _state._transparency)||
|
||||||
(_target._color_write != _state._color_write)||
|
(_target._color_write != _state._color_write)||
|
||||||
(_target._color_blend != _state._color_blend)) {
|
(_target._color_blend != _state._color_blend)) {
|
||||||
@ -4685,14 +4649,17 @@ set_state_and_transform(const RenderState *target,
|
|||||||
_state._color_blend = _target._color_blend;
|
_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) {
|
if (_target._texture != _state._texture) {
|
||||||
do_issue_texture();
|
do_issue_texture();
|
||||||
_state._texture = _target._texture;
|
_state._texture = _target._texture;
|
||||||
|
_state._tex_gen = 0;
|
||||||
// Changing the set of texture stages will require us to reissue the
|
_state._tex_matrix = 0;
|
||||||
// texgen and texmat attribs.
|
|
||||||
needs_tex_gen = true;
|
|
||||||
needs_tex_mat = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_target._material != _state._material) {
|
if (_target._material != _state._material) {
|
||||||
@ -4708,23 +4675,354 @@ set_state_and_transform(const RenderState *target,
|
|||||||
// If one of the previously-loaded TexGen modes modified the texture
|
// If one of the previously-loaded TexGen modes modified the texture
|
||||||
// matrix, then if either state changed, we have to change both of
|
// matrix, then if either state changed, we have to change both of
|
||||||
// them now.
|
// them now.
|
||||||
if (_tex_gen_modifies_mat && (needs_tex_mat || needs_tex_gen)) {
|
if (_tex_gen_modifies_mat) {
|
||||||
needs_tex_mat = true;
|
if ((_target._tex_gen != _state._tex_gen) ||
|
||||||
needs_tex_gen = true;
|
(_target._tex_matrix != _state._tex_matrix)) {
|
||||||
|
_state._tex_matrix = 0;
|
||||||
|
_state._tex_gen = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply the texture matrix, if needed.
|
if (_target._tex_matrix != _state._tex_matrix) {
|
||||||
if (needs_tex_mat) {
|
do_issue_tex_matrix();
|
||||||
int num_stages = _state._texture->get_num_on_stages();
|
_state._tex_matrix = _target._tex_matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_target._tex_gen != _state._tex_gen) {
|
||||||
|
do_issue_tex_gen();
|
||||||
|
_state._tex_gen = _target._tex_gen;
|
||||||
|
}
|
||||||
|
|
||||||
|
_state_rs = _target_rs;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GLGraphicsStateGuardian::free_pointers
|
||||||
|
// Access: Protected, Virtual
|
||||||
|
// Description: Frees some memory that was explicitly allocated
|
||||||
|
// within the glgsg.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void CLP(GraphicsStateGuardian)::
|
||||||
|
free_pointers() {
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GLGraphicsStateGuardian::do_auto_rescale_normal
|
||||||
|
// Access: Protected
|
||||||
|
// Description: Issues the appropriate GL commands to either rescale
|
||||||
|
// or normalize the normals according to the current
|
||||||
|
// transform.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void CLP(GraphicsStateGuardian)::
|
||||||
|
do_auto_rescale_normal() {
|
||||||
|
if (_external_transform->has_identity_scale()) {
|
||||||
|
// If there's no scale at all, don't do anything.
|
||||||
|
GLP(Disable)(GL_NORMALIZE);
|
||||||
|
if (_supports_rescale_normal && support_rescale_normal) {
|
||||||
|
GLP(Disable)(GL_RESCALE_NORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (_external_transform->has_uniform_scale()) {
|
||||||
|
// There's a uniform scale; use the rescale feature if available.
|
||||||
|
if (_supports_rescale_normal && support_rescale_normal) {
|
||||||
|
GLP(Enable)(GL_RESCALE_NORMAL);
|
||||||
|
GLP(Disable)(GL_NORMALIZE);
|
||||||
|
} else {
|
||||||
|
GLP(Enable)(GL_NORMALIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// If there's a non-uniform scale, normalize everything.
|
||||||
|
GLP(Enable)(GL_NORMALIZE);
|
||||||
|
if (_supports_rescale_normal && support_rescale_normal) {
|
||||||
|
GLP(Disable)(GL_RESCALE_NORMAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GLGraphicsStateGuardian::do_issue_texture
|
||||||
|
// Access: Protected, Virtual
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
_texture_involves_color_scale = false;
|
||||||
|
|
||||||
|
int last_saved_result = -1;
|
||||||
|
int last_stage = -1;
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < num_stages; i++) {
|
||||||
|
TextureStage *stage = _target._texture->get_on_stage(i);
|
||||||
|
Texture *texture = _target._texture->get_on_texture(stage);
|
||||||
|
nassertv(texture != (Texture *)NULL);
|
||||||
|
|
||||||
|
if (i >= num_old_stages ||
|
||||||
|
_state._texture == (TextureAttrib *)NULL ||
|
||||||
|
stage != _state._texture->get_on_stage(i) ||
|
||||||
|
texture != _state._texture->get_on_texture(stage) ||
|
||||||
|
stage->involves_color_scale()) {
|
||||||
|
// Stage i has changed. Issue the texture on this stage.
|
||||||
|
_glActiveTexture(GL_TEXTURE0 + i);
|
||||||
|
|
||||||
|
// First, turn off the previous texture mode.
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
TextureContext *tc = texture->prepare_now(_prepared_objects, this);
|
||||||
|
if (tc == (TextureContext *)NULL) {
|
||||||
|
// Something wrong with this texture; skip it.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then, turn on the current texture mode.
|
||||||
|
GLenum target = get_texture_target(texture->get_texture_type());
|
||||||
|
if (target == GL_NONE) {
|
||||||
|
// Unsupported texture mode.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
GLP(Enable)(target);
|
||||||
|
|
||||||
|
apply_texture(tc);
|
||||||
|
|
||||||
|
if (stage->involves_color_scale() && _color_scale_enabled) {
|
||||||
|
Colorf color = stage->get_color();
|
||||||
|
color.set(color[0] * _current_color_scale[0],
|
||||||
|
color[1] * _current_color_scale[1],
|
||||||
|
color[2] * _current_color_scale[2],
|
||||||
|
color[3] * _current_color_scale[3]);
|
||||||
|
_texture_involves_color_scale = true;
|
||||||
|
GLP(TexEnvfv)(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color.get_data());
|
||||||
|
} else {
|
||||||
|
GLP(TexEnvfv)(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, stage->get_color().get_data());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stage->get_mode() == TextureStage::M_decal) {
|
||||||
|
if (texture->get_num_components() < 3 && _supports_texture_combine) {
|
||||||
|
// Make a special case for 1- and 2-channel decal textures.
|
||||||
|
// OpenGL does not define their use with GL_DECAL for some
|
||||||
|
// reason, so implement them using the combiner instead.
|
||||||
|
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
||||||
|
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
|
||||||
|
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_RGB_SCALE, 1);
|
||||||
|
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1);
|
||||||
|
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
|
||||||
|
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
|
||||||
|
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PREVIOUS);
|
||||||
|
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
|
||||||
|
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_TEXTURE);
|
||||||
|
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Normal 3- and 4-channel decal textures.
|
||||||
|
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (stage->get_mode() == TextureStage::M_combine) {
|
||||||
|
if (!_supports_texture_combine) {
|
||||||
|
GLCAT.warning()
|
||||||
|
<< "TextureStage::M_combine mode is not supported.\n";
|
||||||
|
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||||
|
} else {
|
||||||
|
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
||||||
|
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
|
||||||
|
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_RGB_SCALE, stage->get_rgb_scale());
|
||||||
|
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_ALPHA_SCALE, stage->get_alpha_scale());
|
||||||
|
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_COMBINE_RGB,
|
||||||
|
get_texture_combine_type(stage->get_combine_rgb_mode()));
|
||||||
|
|
||||||
|
switch (stage->get_num_combine_rgb_operands()) {
|
||||||
|
case 3:
|
||||||
|
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC2_RGB,
|
||||||
|
get_texture_src_type(stage->get_combine_rgb_source2(),
|
||||||
|
last_stage, last_saved_result, i));
|
||||||
|
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND2_RGB,
|
||||||
|
get_texture_operand_type(stage->get_combine_rgb_operand2()));
|
||||||
|
// fall through
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC1_RGB,
|
||||||
|
get_texture_src_type(stage->get_combine_rgb_source1(),
|
||||||
|
last_stage, last_saved_result, i));
|
||||||
|
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND1_RGB,
|
||||||
|
get_texture_operand_type(stage->get_combine_rgb_operand1()));
|
||||||
|
// fall through
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC0_RGB,
|
||||||
|
get_texture_src_type(stage->get_combine_rgb_source0(),
|
||||||
|
last_stage, last_saved_result, i));
|
||||||
|
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND0_RGB,
|
||||||
|
get_texture_operand_type(stage->get_combine_rgb_operand0()));
|
||||||
|
// fall through
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_COMBINE_ALPHA,
|
||||||
|
get_texture_combine_type(stage->get_combine_alpha_mode()));
|
||||||
|
|
||||||
|
switch (stage->get_num_combine_alpha_operands()) {
|
||||||
|
case 3:
|
||||||
|
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC2_ALPHA,
|
||||||
|
get_texture_src_type(stage->get_combine_alpha_source2(),
|
||||||
|
last_stage, last_saved_result, i));
|
||||||
|
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA,
|
||||||
|
get_texture_operand_type(stage->get_combine_alpha_operand2()));
|
||||||
|
// fall through
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC1_ALPHA,
|
||||||
|
get_texture_src_type(stage->get_combine_alpha_source1(),
|
||||||
|
last_stage, last_saved_result, i));
|
||||||
|
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA,
|
||||||
|
get_texture_operand_type(stage->get_combine_alpha_operand1()));
|
||||||
|
// fall through
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC0_ALPHA,
|
||||||
|
get_texture_src_type(stage->get_combine_alpha_source0(),
|
||||||
|
last_stage, last_saved_result, i));
|
||||||
|
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA,
|
||||||
|
get_texture_operand_type(stage->get_combine_alpha_operand0()));
|
||||||
|
// fall through
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
GLint glmode = get_texture_apply_mode_type(stage->get_mode());
|
||||||
|
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, glmode);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLP(MatrixMode)(GL_TEXTURE);
|
||||||
|
if (_target._tex_matrix->has_stage(stage)) {
|
||||||
|
GLP(LoadMatrixf)(_state._tex_matrix->get_mat(stage).get_data());
|
||||||
|
} else {
|
||||||
|
GLP(LoadIdentity)();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stage->get_saved_result()) {
|
||||||
|
// This texture's result will be "saved" for a future stage's
|
||||||
|
// input.
|
||||||
|
last_saved_result = i;
|
||||||
|
} else {
|
||||||
|
// This is a regular texture stage; it will be the "previous"
|
||||||
|
// input for the next stage.
|
||||||
|
last_stage = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable the texture stages that are no longer used.
|
||||||
|
for (i = num_stages; 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::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);
|
nassertv(num_stages <= _max_texture_stages);
|
||||||
|
|
||||||
for (int i = 0; i < num_stages; i++) {
|
for (int i = 0; i < num_stages; i++) {
|
||||||
TextureStage *stage = _state._texture->get_on_stage(i);
|
TextureStage *stage = _target._texture->get_on_stage(i);
|
||||||
_glActiveTexture(GL_TEXTURE0 + i);
|
_glActiveTexture(GL_TEXTURE0 + i);
|
||||||
|
|
||||||
GLP(MatrixMode)(GL_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());
|
GLP(LoadMatrixf)(_target._tex_matrix->get_mat(stage).get_data());
|
||||||
} else {
|
} else {
|
||||||
GLP(LoadIdentity)();
|
GLP(LoadIdentity)();
|
||||||
|
|
||||||
@ -4740,10 +5038,16 @@ set_state_and_transform(const RenderState *target,
|
|||||||
report_my_gl_errors();
|
report_my_gl_errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needs_tex_gen) {
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GLGraphicsStateGuardian::do_issue_tex_gen
|
||||||
|
// Access: Protected
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void CLP(GraphicsStateGuardian)::
|
||||||
|
do_issue_tex_gen() {
|
||||||
bool force_normal = false;
|
bool force_normal = false;
|
||||||
|
|
||||||
int num_stages = _state._texture->get_num_on_stages();
|
int num_stages = _target._texture->get_num_on_stages();
|
||||||
nassertv(num_stages <= _max_texture_stages);
|
nassertv(num_stages <= _max_texture_stages);
|
||||||
|
|
||||||
// These are passed in for the four OBJECT_PLANE or EYE_PLANE
|
// These are passed in for the four OBJECT_PLANE or EYE_PLANE
|
||||||
@ -4761,7 +5065,7 @@ set_state_and_transform(const RenderState *target,
|
|||||||
bool got_point_sprites = false;
|
bool got_point_sprites = false;
|
||||||
|
|
||||||
for (int i = 0; i < num_stages; i++) {
|
for (int i = 0; i < num_stages; i++) {
|
||||||
TextureStage *stage = _state._texture->get_on_stage(i);
|
TextureStage *stage = _target._texture->get_on_stage(i);
|
||||||
_glActiveTexture(GL_TEXTURE0 + i);
|
_glActiveTexture(GL_TEXTURE0 + i);
|
||||||
GLP(Disable)(GL_TEXTURE_GEN_S);
|
GLP(Disable)(GL_TEXTURE_GEN_S);
|
||||||
GLP(Disable)(GL_TEXTURE_GEN_T);
|
GLP(Disable)(GL_TEXTURE_GEN_T);
|
||||||
@ -4771,7 +5075,7 @@ set_state_and_transform(const RenderState *target,
|
|||||||
GLP(TexEnvi)(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_FALSE);
|
GLP(TexEnvi)(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
TexGenAttrib::Mode mode = _state._tex_gen->get_mode(stage);
|
TexGenAttrib::Mode mode = _target._tex_gen->get_mode(stage);
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case TexGenAttrib::M_off:
|
case TexGenAttrib::M_off:
|
||||||
case TexGenAttrib::M_light_vector:
|
case TexGenAttrib::M_light_vector:
|
||||||
@ -4980,262 +5284,6 @@ set_state_and_transform(const RenderState *target,
|
|||||||
report_my_gl_errors();
|
report_my_gl_errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
_state_rs = _target_rs;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: GLGraphicsStateGuardian::free_pointers
|
|
||||||
// Access: Protected, Virtual
|
|
||||||
// Description: Frees some memory that was explicitly allocated
|
|
||||||
// within the glgsg.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
void CLP(GraphicsStateGuardian)::
|
|
||||||
free_pointers() {
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: GLGraphicsStateGuardian::do_auto_rescale_normal
|
|
||||||
// Access: Protected
|
|
||||||
// Description: Issues the appropriate GL commands to either rescale
|
|
||||||
// or normalize the normals according to the current
|
|
||||||
// transform.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
void CLP(GraphicsStateGuardian)::
|
|
||||||
do_auto_rescale_normal() {
|
|
||||||
if (_external_transform->has_identity_scale()) {
|
|
||||||
// If there's no scale at all, don't do anything.
|
|
||||||
GLP(Disable)(GL_NORMALIZE);
|
|
||||||
if (_supports_rescale_normal && support_rescale_normal) {
|
|
||||||
GLP(Disable)(GL_RESCALE_NORMAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (_external_transform->has_uniform_scale()) {
|
|
||||||
// There's a uniform scale; use the rescale feature if available.
|
|
||||||
if (_supports_rescale_normal && support_rescale_normal) {
|
|
||||||
GLP(Enable)(GL_RESCALE_NORMAL);
|
|
||||||
GLP(Disable)(GL_NORMALIZE);
|
|
||||||
} else {
|
|
||||||
GLP(Enable)(GL_NORMALIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// If there's a non-uniform scale, normalize everything.
|
|
||||||
GLP(Enable)(GL_NORMALIZE);
|
|
||||||
if (_supports_rescale_normal && support_rescale_normal) {
|
|
||||||
GLP(Disable)(GL_RESCALE_NORMAL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: GLGraphicsStateGuardian::do_issue_texture
|
|
||||||
// Access: Protected, Virtual
|
|
||||||
// Description: This is called by finish_modify_state() when the
|
|
||||||
// texture state has changed.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
void CLP(GraphicsStateGuardian)::
|
|
||||||
do_issue_texture() {
|
|
||||||
DO_PSTATS_STUFF(_texture_state_pcollector.add_level(1));
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
_texture_involves_color_scale = false;
|
|
||||||
|
|
||||||
int last_saved_result = -1;
|
|
||||||
int last_stage = -1;
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < num_stages; i++) {
|
|
||||||
TextureStage *stage = _target._texture->get_on_stage(i);
|
|
||||||
Texture *texture = _target._texture->get_on_texture(stage);
|
|
||||||
nassertv(texture != (Texture *)NULL);
|
|
||||||
|
|
||||||
if (i >= num_old_stages ||
|
|
||||||
_state._texture == (TextureAttrib *)NULL ||
|
|
||||||
stage != _state._texture->get_on_stage(i) ||
|
|
||||||
texture != _state._texture->get_on_texture(stage) ||
|
|
||||||
stage->involves_color_scale()) {
|
|
||||||
// Stage i has changed. Issue the texture on this stage.
|
|
||||||
_glActiveTexture(GL_TEXTURE0 + i);
|
|
||||||
|
|
||||||
// First, turn off the previous texture mode.
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
TextureContext *tc = texture->prepare_now(_prepared_objects, this);
|
|
||||||
if (tc == (TextureContext *)NULL) {
|
|
||||||
// Something wrong with this texture; skip it.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Then, turn on the current texture mode.
|
|
||||||
GLenum target = get_texture_target(texture->get_texture_type());
|
|
||||||
if (target == GL_NONE) {
|
|
||||||
// Unsupported texture mode.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
GLP(Enable)(target);
|
|
||||||
|
|
||||||
apply_texture(tc);
|
|
||||||
|
|
||||||
if (stage->involves_color_scale() && _color_scale_enabled) {
|
|
||||||
Colorf color = stage->get_color();
|
|
||||||
color.set(color[0] * _current_color_scale[0],
|
|
||||||
color[1] * _current_color_scale[1],
|
|
||||||
color[2] * _current_color_scale[2],
|
|
||||||
color[3] * _current_color_scale[3]);
|
|
||||||
_texture_involves_color_scale = true;
|
|
||||||
GLP(TexEnvfv)(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color.get_data());
|
|
||||||
} else {
|
|
||||||
GLP(TexEnvfv)(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, stage->get_color().get_data());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stage->get_mode() == TextureStage::M_decal) {
|
|
||||||
if (texture->get_num_components() < 3 && _supports_texture_combine) {
|
|
||||||
// Make a special case for 1- and 2-channel decal textures.
|
|
||||||
// OpenGL does not define their use with GL_DECAL for some
|
|
||||||
// reason, so implement them using the combiner instead.
|
|
||||||
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
|
||||||
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
|
|
||||||
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_RGB_SCALE, 1);
|
|
||||||
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1);
|
|
||||||
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
|
|
||||||
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
|
|
||||||
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PREVIOUS);
|
|
||||||
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
|
|
||||||
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_TEXTURE);
|
|
||||||
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// Normal 3- and 4-channel decal textures.
|
|
||||||
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (stage->get_mode() == TextureStage::M_combine) {
|
|
||||||
if (!_supports_texture_combine) {
|
|
||||||
GLCAT.warning()
|
|
||||||
<< "TextureStage::M_combine mode is not supported.\n";
|
|
||||||
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
|
||||||
} else {
|
|
||||||
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
|
||||||
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
|
|
||||||
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_RGB_SCALE, stage->get_rgb_scale());
|
|
||||||
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_ALPHA_SCALE, stage->get_alpha_scale());
|
|
||||||
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_COMBINE_RGB,
|
|
||||||
get_texture_combine_type(stage->get_combine_rgb_mode()));
|
|
||||||
|
|
||||||
switch (stage->get_num_combine_rgb_operands()) {
|
|
||||||
case 3:
|
|
||||||
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC2_RGB,
|
|
||||||
get_texture_src_type(stage->get_combine_rgb_source2(),
|
|
||||||
last_stage, last_saved_result, i));
|
|
||||||
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND2_RGB,
|
|
||||||
get_texture_operand_type(stage->get_combine_rgb_operand2()));
|
|
||||||
// fall through
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC1_RGB,
|
|
||||||
get_texture_src_type(stage->get_combine_rgb_source1(),
|
|
||||||
last_stage, last_saved_result, i));
|
|
||||||
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND1_RGB,
|
|
||||||
get_texture_operand_type(stage->get_combine_rgb_operand1()));
|
|
||||||
// fall through
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC0_RGB,
|
|
||||||
get_texture_src_type(stage->get_combine_rgb_source0(),
|
|
||||||
last_stage, last_saved_result, i));
|
|
||||||
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND0_RGB,
|
|
||||||
get_texture_operand_type(stage->get_combine_rgb_operand0()));
|
|
||||||
// fall through
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_COMBINE_ALPHA,
|
|
||||||
get_texture_combine_type(stage->get_combine_alpha_mode()));
|
|
||||||
|
|
||||||
switch (stage->get_num_combine_alpha_operands()) {
|
|
||||||
case 3:
|
|
||||||
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC2_ALPHA,
|
|
||||||
get_texture_src_type(stage->get_combine_alpha_source2(),
|
|
||||||
last_stage, last_saved_result, i));
|
|
||||||
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA,
|
|
||||||
get_texture_operand_type(stage->get_combine_alpha_operand2()));
|
|
||||||
// fall through
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC1_ALPHA,
|
|
||||||
get_texture_src_type(stage->get_combine_alpha_source1(),
|
|
||||||
last_stage, last_saved_result, i));
|
|
||||||
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA,
|
|
||||||
get_texture_operand_type(stage->get_combine_alpha_operand1()));
|
|
||||||
// fall through
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC0_ALPHA,
|
|
||||||
get_texture_src_type(stage->get_combine_alpha_source0(),
|
|
||||||
last_stage, last_saved_result, i));
|
|
||||||
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA,
|
|
||||||
get_texture_operand_type(stage->get_combine_alpha_operand0()));
|
|
||||||
// fall through
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
GLint glmode = get_texture_apply_mode_type(stage->get_mode());
|
|
||||||
GLP(TexEnvi)(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, glmode);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLP(MatrixMode)(GL_TEXTURE);
|
|
||||||
if (_state._tex_matrix->has_stage(stage)) {
|
|
||||||
GLP(LoadMatrixf)(_state._tex_matrix->get_mat(stage).get_data());
|
|
||||||
} else {
|
|
||||||
GLP(LoadIdentity)();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stage->get_saved_result()) {
|
|
||||||
// This texture's result will be "saved" for a future stage's
|
|
||||||
// input.
|
|
||||||
last_saved_result = i;
|
|
||||||
} else {
|
|
||||||
// This is a regular texture stage; it will be the "previous"
|
|
||||||
// input for the next stage.
|
|
||||||
last_stage = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disable the texture stages that are no longer used.
|
|
||||||
for (i = num_stages; 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::specify_texture
|
// Function: GLGraphicsStateGuardian::specify_texture
|
||||||
// Access: Protected
|
// Access: Protected
|
||||||
|
@ -177,6 +177,8 @@ protected:
|
|||||||
void do_issue_material();
|
void do_issue_material();
|
||||||
void do_issue_texture();
|
void do_issue_texture();
|
||||||
void do_issue_blending();
|
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,
|
static bool report_errors_loop(int line, const char *source_file,
|
||||||
GLenum error_code, int &error_count);
|
GLenum error_code, int &error_count);
|
||||||
@ -249,6 +251,8 @@ protected:
|
|||||||
|
|
||||||
void disable_standard_vertex_arrays();
|
void disable_standard_vertex_arrays();
|
||||||
void update_standard_vertex_arrays();
|
void update_standard_vertex_arrays();
|
||||||
|
void disable_standard_texture_bindings();
|
||||||
|
void update_standard_texture_bindings();
|
||||||
|
|
||||||
void do_auto_rescale_normal();
|
void do_auto_rescale_normal();
|
||||||
void specify_texture(Texture *tex);
|
void specify_texture(Texture *tex);
|
||||||
@ -310,6 +314,8 @@ protected:
|
|||||||
CLP(ShaderContext) *_current_shader_context;
|
CLP(ShaderContext) *_current_shader_context;
|
||||||
PT(ShaderExpansion) _vertex_array_shader_expansion;
|
PT(ShaderExpansion) _vertex_array_shader_expansion;
|
||||||
CLP(ShaderContext) *_vertex_array_shader_context;
|
CLP(ShaderContext) *_vertex_array_shader_context;
|
||||||
|
PT(ShaderExpansion) _texture_binding_shader_expansion;
|
||||||
|
CLP(ShaderContext) *_texture_binding_shader_context;
|
||||||
|
|
||||||
CPT(DisplayRegion) _actual_display_region;
|
CPT(DisplayRegion) _actual_display_region;
|
||||||
|
|
||||||
|
@ -307,6 +307,84 @@ update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg)
|
|||||||
#endif // HAVE_CGGL
|
#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
|
#ifdef HAVE_CGGL
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: GLShaderContext::bind_cg_transform
|
// Function: GLShaderContext::bind_cg_transform
|
||||||
@ -321,6 +399,8 @@ bind_cg_transform(const ShaderTransBind &stb, GSG *gsg)
|
|||||||
|
|
||||||
if (stb.src_name == InternalName::get_camera()) {
|
if (stb.src_name == InternalName::get_camera()) {
|
||||||
src = TransformState::make_identity();
|
src = TransformState::make_identity();
|
||||||
|
} else if (stb.src_name == InternalName::get_view()) {
|
||||||
|
src = gsg->_cs_transform;
|
||||||
} else if (stb.src_name == InternalName::get_model()) {
|
} else if (stb.src_name == InternalName::get_model()) {
|
||||||
src = gsg->get_transform();
|
src = gsg->get_transform();
|
||||||
} else if (stb.src_name == InternalName::get_world()) {
|
} 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()) {
|
if (stb.rel_name == InternalName::get_camera()) {
|
||||||
rel = TransformState::make_identity();
|
rel = TransformState::make_identity();
|
||||||
|
} else if (stb.src_name == InternalName::get_view()) {
|
||||||
|
rel = gsg->_cs_transform;
|
||||||
} else if (stb.rel_name == InternalName::get_model()) {
|
} else if (stb.rel_name == InternalName::get_model()) {
|
||||||
rel = gsg->get_transform();
|
rel = gsg->get_transform();
|
||||||
} else if (stb.rel_name == InternalName::get_world()) {
|
} else if (stb.rel_name == InternalName::get_world()) {
|
||||||
@ -498,7 +580,10 @@ bool CLP(ShaderContext)::
|
|||||||
errchk_cg_parameter_sampler(CGparameter p)
|
errchk_cg_parameter_sampler(CGparameter p)
|
||||||
{
|
{
|
||||||
CGtype t = cgGetParameterType(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");
|
errchk_cg_output(p, "parameter should have a 'sampler' type");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -744,8 +829,21 @@ compile_cg_parameter(CGparameter p)
|
|||||||
(!errchk_cg_parameter_variance(p, CG_UNIFORM)) ||
|
(!errchk_cg_parameter_variance(p, CG_UNIFORM)) ||
|
||||||
(!errchk_cg_parameter_sampler(p)))
|
(!errchk_cg_parameter_sampler(p)))
|
||||||
return false;
|
return false;
|
||||||
// IMPLEMENT ME
|
ShaderTexBind bind;
|
||||||
return true; // Cg handles this automatically.
|
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") {
|
if (pieces[0] == "k") {
|
||||||
@ -753,14 +851,53 @@ compile_cg_parameter(CGparameter p)
|
|||||||
(!errchk_cg_parameter_direction(p, CG_IN)) ||
|
(!errchk_cg_parameter_direction(p, CG_IN)) ||
|
||||||
(!errchk_cg_parameter_variance(p, CG_UNIFORM)))
|
(!errchk_cg_parameter_variance(p, CG_UNIFORM)))
|
||||||
return false;
|
return false;
|
||||||
|
switch (cgGetParameterType(p)) {
|
||||||
|
case CG_FLOAT4: {
|
||||||
ShaderArgBind bind;
|
ShaderArgBind bind;
|
||||||
bind.parameter = p;
|
bind.parameter = p;
|
||||||
bind.name = InternalName::make(pieces[1]);
|
bind.name = InternalName::make(pieces[1]);
|
||||||
switch (cgGetParameterType(p)) {
|
_cg_fbind.push_back(bind);
|
||||||
case CG_FLOAT4: _cg_fbind.push_back(bind); break;
|
break;
|
||||||
case CG_SAMPLER2D: _cg_tbind2d.push_back(bind); break;
|
}
|
||||||
case CG_SAMPLER3D: _cg_tbind3d.push_back(bind); break;
|
case CG_FLOAT4x4: {
|
||||||
case CG_FLOAT4x4: _cg_npbind.push_back(bind); break;
|
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:
|
default:
|
||||||
errchk_cg_output(p, "Invalid type for a k-parameter");
|
errchk_cg_output(p, "Invalid type for a k-parameter");
|
||||||
return false;
|
return false;
|
||||||
|
@ -45,6 +45,8 @@ public:
|
|||||||
void issue_transform(GSG *gsg);
|
void issue_transform(GSG *gsg);
|
||||||
void disable_shader_vertex_arrays(GSG *gsg);
|
void disable_shader_vertex_arrays(GSG *gsg);
|
||||||
void update_shader_vertex_arrays(CLP(ShaderContext) *prev, 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:
|
private:
|
||||||
|
|
||||||
@ -58,6 +60,12 @@ private:
|
|||||||
CGparameter parameter;
|
CGparameter parameter;
|
||||||
PT(InternalName) name;
|
PT(InternalName) name;
|
||||||
};
|
};
|
||||||
|
struct ShaderTexBind {
|
||||||
|
CGparameter parameter;
|
||||||
|
PT(InternalName) name;
|
||||||
|
int stage;
|
||||||
|
int desiredtype;
|
||||||
|
};
|
||||||
struct ShaderTransBind {
|
struct ShaderTransBind {
|
||||||
CGparameter parameter;
|
CGparameter parameter;
|
||||||
PT(InternalName) src_name;
|
PT(InternalName) src_name;
|
||||||
@ -76,10 +84,9 @@ private:
|
|||||||
// These arrays contain lists of "bindings." They
|
// These arrays contain lists of "bindings." They
|
||||||
// tell us how to fill the shader's input parameters.
|
// tell us how to fill the shader's input parameters.
|
||||||
vector <ShaderAutoBind> _cg_autobind;
|
vector <ShaderAutoBind> _cg_autobind;
|
||||||
vector <ShaderArgBind> _cg_tbind2d;
|
|
||||||
vector <ShaderArgBind> _cg_tbind3d;
|
|
||||||
vector <ShaderArgBind> _cg_fbind;
|
vector <ShaderArgBind> _cg_fbind;
|
||||||
vector <ShaderArgBind> _cg_npbind;
|
vector <ShaderArgBind> _cg_npbind;
|
||||||
|
vector <ShaderTexBind> _cg_texbind;
|
||||||
vector <ShaderTransBind> _cg_transform_bind;
|
vector <ShaderTransBind> _cg_transform_bind;
|
||||||
vector <ShaderTransBind> _cg_parameter_bind;
|
vector <ShaderTransBind> _cg_parameter_bind;
|
||||||
vector <ShaderVarying> _cg_varying;
|
vector <ShaderVarying> _cg_varying;
|
||||||
|
@ -417,6 +417,20 @@ get_model() {
|
|||||||
return _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
|
// Function: InternalName::output operator
|
||||||
// Access: Public
|
// Access: Public
|
||||||
|
@ -42,6 +42,7 @@ PT(InternalName) InternalName::_index;
|
|||||||
PT(InternalName) InternalName::_world;
|
PT(InternalName) InternalName::_world;
|
||||||
PT(InternalName) InternalName::_camera;
|
PT(InternalName) InternalName::_camera;
|
||||||
PT(InternalName) InternalName::_model;
|
PT(InternalName) InternalName::_model;
|
||||||
|
PT(InternalName) InternalName::_view;
|
||||||
|
|
||||||
TypeHandle InternalName::_type_handle;
|
TypeHandle InternalName::_type_handle;
|
||||||
TypeHandle InternalName::_texcoord_type_handle;
|
TypeHandle InternalName::_texcoord_type_handle;
|
||||||
|
@ -84,6 +84,7 @@ PUBLISHED:
|
|||||||
INLINE static PT(InternalName) get_world();
|
INLINE static PT(InternalName) get_world();
|
||||||
INLINE static PT(InternalName) get_camera();
|
INLINE static PT(InternalName) get_camera();
|
||||||
INLINE static PT(InternalName) get_model();
|
INLINE static PT(InternalName) get_model();
|
||||||
|
INLINE static PT(InternalName) get_view();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PT(InternalName) _parent;
|
PT(InternalName) _parent;
|
||||||
@ -111,6 +112,7 @@ private:
|
|||||||
static PT(InternalName) _world;
|
static PT(InternalName) _world;
|
||||||
static PT(InternalName) _camera;
|
static PT(InternalName) _camera;
|
||||||
static PT(InternalName) _model;
|
static PT(InternalName) _model;
|
||||||
|
static PT(InternalName) _view;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Datagram stuff
|
// Datagram stuff
|
||||||
|
Loading…
x
Reference in New Issue
Block a user