mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
Shader context input state tracking system, for more efficiently updating shader inputs
This commit is contained in:
parent
0cecab3124
commit
e4c3301bd0
@ -52,15 +52,5 @@ uses_custom_vertex_arrays() {
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLCgShaderContext::uses_custom_texture_bindings
|
||||
// Access: Public
|
||||
// Description: Always true, for now.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool CLP(CgShaderContext)::
|
||||
uses_custom_texture_bindings() {
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // OPENGLES_1
|
||||
|
||||
|
@ -46,6 +46,7 @@ CLP(CgShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderConte
|
||||
_color_attrib_index = CA_color;
|
||||
_transform_table_param = 0;
|
||||
_slider_table_param = 0;
|
||||
_frame_number = -1;
|
||||
|
||||
nassertv(s->get_language() == Shader::SL_Cg);
|
||||
|
||||
@ -361,13 +362,8 @@ release_resources() {
|
||||
// input parameters.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(CgShaderContext)::
|
||||
bind(bool reissue_parameters) {
|
||||
bind() {
|
||||
if (_cg_program != 0) {
|
||||
if (reissue_parameters) {
|
||||
// Pass in k-parameters and transform-parameters
|
||||
issue_parameters(Shader::SSD_general);
|
||||
}
|
||||
|
||||
// Bind the shaders.
|
||||
cgGLEnableProgramProfiles(_cg_program);
|
||||
cgGLBindProgram(_cg_program);
|
||||
@ -397,6 +393,88 @@ unbind() {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLCgShaderContext::set_state_and_transform
|
||||
// Access: Public
|
||||
// Description: This function gets called whenever the RenderState
|
||||
// or TransformState has changed, but the Shader
|
||||
// itself has not changed. It loads new values into the
|
||||
// shader's parameters.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(CgShaderContext)::
|
||||
set_state_and_transform(const RenderState *target_rs,
|
||||
const TransformState *modelview_transform,
|
||||
const TransformState *projection_transform) {
|
||||
|
||||
if (!valid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Find out which state properties have changed.
|
||||
int altered = 0;
|
||||
|
||||
if (_modelview_transform != modelview_transform) {
|
||||
_modelview_transform = modelview_transform;
|
||||
altered |= Shader::SSD_transform;
|
||||
}
|
||||
if (_projection_transform != projection_transform) {
|
||||
_projection_transform = projection_transform;
|
||||
altered |= Shader::SSD_projection;
|
||||
}
|
||||
|
||||
if (_state_rs != target_rs) {
|
||||
if (_state_rs == NULL) {
|
||||
// We haven't set any state yet.
|
||||
altered |= Shader::SSD_general;
|
||||
} else {
|
||||
if (_state_rs->get_attrib(ColorAttrib::get_class_slot()) !=
|
||||
target_rs->get_attrib(ColorAttrib::get_class_slot())) {
|
||||
altered |= Shader::SSD_color;
|
||||
}
|
||||
if (_state_rs->get_attrib(ColorScaleAttrib::get_class_slot()) !=
|
||||
target_rs->get_attrib(ColorScaleAttrib::get_class_slot())) {
|
||||
altered |= Shader::SSD_colorscale;
|
||||
}
|
||||
if (_state_rs->get_attrib(MaterialAttrib::get_class_slot()) !=
|
||||
target_rs->get_attrib(MaterialAttrib::get_class_slot())) {
|
||||
altered |= Shader::SSD_material;
|
||||
}
|
||||
if (_state_rs->get_attrib(ShaderAttrib::get_class_slot()) !=
|
||||
target_rs->get_attrib(ShaderAttrib::get_class_slot())) {
|
||||
altered |= Shader::SSD_shaderinputs;
|
||||
}
|
||||
if (_state_rs->get_attrib(FogAttrib::get_class_slot()) !=
|
||||
target_rs->get_attrib(FogAttrib::get_class_slot())) {
|
||||
altered |= Shader::SSD_fog;
|
||||
}
|
||||
if (_state_rs->get_attrib(LightAttrib::get_class_slot()) !=
|
||||
target_rs->get_attrib(LightAttrib::get_class_slot())) {
|
||||
altered |= Shader::SSD_light;
|
||||
}
|
||||
if (_state_rs->get_attrib(ClipPlaneAttrib::get_class_slot()) !=
|
||||
target_rs->get_attrib(ClipPlaneAttrib::get_class_slot())) {
|
||||
altered |= Shader::SSD_clip_planes;
|
||||
}
|
||||
if (_state_rs->get_attrib(TexMatrixAttrib::get_class_slot()) !=
|
||||
target_rs->get_attrib(TexMatrixAttrib::get_class_slot())) {
|
||||
altered |= Shader::SSD_tex_matrix;
|
||||
}
|
||||
}
|
||||
_state_rs = target_rs;
|
||||
}
|
||||
|
||||
// Is this the first time this shader is used this frame?
|
||||
int frame_number = ClockObject::get_global_clock()->get_frame_count();
|
||||
if (frame_number != _frame_number) {
|
||||
altered |= Shader::SSD_frame;
|
||||
_frame_number = frame_number;
|
||||
}
|
||||
|
||||
if (altered != 0) {
|
||||
issue_parameters(altered);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLCgShaderContext::issue_parameters
|
||||
// Access: Public
|
||||
@ -414,49 +492,48 @@ unbind() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(CgShaderContext)::
|
||||
issue_parameters(int altered) {
|
||||
//PStatGPUTimer timer(_glgsg, _glgsg->_draw_set_state_shader_parameters_pcollector);
|
||||
PStatGPUTimer timer(_glgsg, _glgsg->_draw_set_state_shader_parameters_pcollector);
|
||||
|
||||
if (!valid()) {
|
||||
return;
|
||||
if (GLCAT.is_spam()) {
|
||||
GLCAT.spam()
|
||||
<< "Setting uniforms for " << _shader->get_filename()
|
||||
<< " (altered 0x" << hex << altered << dec << ")\n";
|
||||
}
|
||||
|
||||
// Iterate through _ptr parameters
|
||||
for (int i=0; i<(int)_shader->_ptr_spec.size(); i++) {
|
||||
if (altered & (_shader->_ptr_spec[i]._dep[0] | _shader->_ptr_spec[i]._dep[1])) {
|
||||
const Shader::ShaderPtrSpec& _ptr = _shader->_ptr_spec[i];
|
||||
Shader::ShaderPtrData* ptr_data =
|
||||
const_cast< Shader::ShaderPtrData*>(_glgsg->fetch_ptr_parameter(_ptr));
|
||||
// We have no way to track modifications to PTAs, so we assume that
|
||||
// they are modified every frame and when we switch ShaderAttribs.
|
||||
if (altered & (Shader::SSD_shaderinputs | Shader::SSD_frame)) {
|
||||
// Iterate through _ptr parameters
|
||||
for (int i = 0; i < (int)_shader->_ptr_spec.size(); ++i) {
|
||||
Shader::ShaderPtrSpec &spec = _shader->_ptr_spec[i];
|
||||
|
||||
const Shader::ShaderPtrData *ptr_data =_glgsg->fetch_ptr_parameter(spec);
|
||||
if (ptr_data == NULL){ //the input is not contained in ShaderPtrData
|
||||
release_resources();
|
||||
return;
|
||||
}
|
||||
//check if the data must be shipped to the GPU
|
||||
/*if (!ptr_data->_updated)
|
||||
continue;
|
||||
ptr_data->_updated = false;*/
|
||||
|
||||
//Check if the size of the shader input and ptr_data match
|
||||
int input_size = _ptr._dim[0] * _ptr._dim[1] * _ptr._dim[2];
|
||||
int input_size = spec._dim[0] * spec._dim[1] * spec._dim[2];
|
||||
|
||||
// dimension is negative only if the parameter had the (deprecated)k_ prefix.
|
||||
if ((input_size > ptr_data->_size) && (_ptr._dim[0] > 0)) {
|
||||
GLCAT.error() << _ptr._id._name << ": incorrect number of elements, expected "
|
||||
if ((input_size > ptr_data->_size) && (spec._dim[0] > 0)) {
|
||||
GLCAT.error() << spec._id._name << ": incorrect number of elements, expected "
|
||||
<< input_size <<" got " << ptr_data->_size << "\n";
|
||||
release_resources();
|
||||
return;
|
||||
}
|
||||
CGparameter p = _cg_parameter_map[_ptr._id._seqno];
|
||||
CGparameter p = _cg_parameter_map[spec._id._seqno];
|
||||
|
||||
switch (ptr_data->_type) {
|
||||
case Shader::SPT_float:
|
||||
switch(_ptr._info._class) {
|
||||
switch (spec._info._class) {
|
||||
case Shader::SAC_scalar:
|
||||
cgSetParameter1fv(p, (float*)ptr_data->_ptr);
|
||||
continue;
|
||||
|
||||
case Shader::SAC_vector:
|
||||
switch (_ptr._info._type) {
|
||||
switch (spec._info._type) {
|
||||
case Shader::SAT_vec1:
|
||||
cgSetParameter1fv(p, (float*)ptr_data->_ptr);
|
||||
continue;
|
||||
@ -479,22 +556,22 @@ issue_parameters(int altered) {
|
||||
continue;
|
||||
|
||||
case Shader::SAC_array:
|
||||
switch (_ptr._info._subclass) {
|
||||
switch (spec._info._subclass) {
|
||||
case Shader::SAC_scalar:
|
||||
cgGLSetParameterArray1f(p, 0, _ptr._dim[0], (float*)ptr_data->_ptr);
|
||||
cgGLSetParameterArray1f(p, 0, spec._dim[0], (float*)ptr_data->_ptr);
|
||||
continue;
|
||||
case Shader::SAC_vector:
|
||||
switch (_ptr._dim[2]) {
|
||||
case 1: cgGLSetParameterArray1f(p, 0, _ptr._dim[0], (float*)ptr_data->_ptr); continue;
|
||||
case 2: cgGLSetParameterArray2f(p, 0, _ptr._dim[0], (float*)ptr_data->_ptr); continue;
|
||||
case 3: cgGLSetParameterArray3f(p, 0, _ptr._dim[0], (float*)ptr_data->_ptr); continue;
|
||||
case 4: cgGLSetParameterArray4f(p, 0, _ptr._dim[0], (float*)ptr_data->_ptr); continue;
|
||||
switch (spec._dim[2]) {
|
||||
case 1: cgGLSetParameterArray1f(p, 0, spec._dim[0], (float*)ptr_data->_ptr); continue;
|
||||
case 2: cgGLSetParameterArray2f(p, 0, spec._dim[0], (float*)ptr_data->_ptr); continue;
|
||||
case 3: cgGLSetParameterArray3f(p, 0, spec._dim[0], (float*)ptr_data->_ptr); continue;
|
||||
case 4: cgGLSetParameterArray4f(p, 0, spec._dim[0], (float*)ptr_data->_ptr); continue;
|
||||
default:
|
||||
nassertd(_ptr._dim[2] > 0 && _ptr._dim[2] <= 4) continue;
|
||||
nassertd(spec._dim[2] > 0 && spec._dim[2] <= 4) continue;
|
||||
}
|
||||
continue;
|
||||
case Shader::SAC_matrix:
|
||||
cgGLSetMatrixParameterArrayfc(p, 0, _ptr._dim[0], (float*)ptr_data->_ptr);
|
||||
cgGLSetMatrixParameterArrayfc(p, 0, spec._dim[0], (float*)ptr_data->_ptr);
|
||||
continue;
|
||||
default:
|
||||
nassertd(false) continue;
|
||||
@ -504,13 +581,13 @@ issue_parameters(int altered) {
|
||||
}
|
||||
|
||||
case Shader::SPT_double:
|
||||
switch(_ptr._info._class) {
|
||||
switch (spec._info._class) {
|
||||
case Shader::SAC_scalar:
|
||||
cgSetParameter1dv(p, (double*)ptr_data->_ptr);
|
||||
continue;
|
||||
|
||||
case Shader::SAC_vector:
|
||||
switch (_ptr._info._type) {
|
||||
switch (spec._info._type) {
|
||||
case Shader::SAT_vec1:
|
||||
cgSetParameter1dv(p, (double*)ptr_data->_ptr);
|
||||
continue;
|
||||
@ -533,22 +610,22 @@ issue_parameters(int altered) {
|
||||
continue;
|
||||
|
||||
case Shader::SAC_array:
|
||||
switch (_ptr._info._subclass) {
|
||||
switch (spec._info._subclass) {
|
||||
case Shader::SAC_scalar:
|
||||
cgGLSetParameterArray1d(p, 0, _ptr._dim[0], (double*)ptr_data->_ptr);
|
||||
cgGLSetParameterArray1d(p, 0, spec._dim[0], (double*)ptr_data->_ptr);
|
||||
continue;
|
||||
case Shader::SAC_vector:
|
||||
switch (_ptr._dim[2]) {
|
||||
case 1: cgGLSetParameterArray1d(p, 0, _ptr._dim[0], (double*)ptr_data->_ptr); continue;
|
||||
case 2: cgGLSetParameterArray2d(p, 0, _ptr._dim[0], (double*)ptr_data->_ptr); continue;
|
||||
case 3: cgGLSetParameterArray3d(p, 0, _ptr._dim[0], (double*)ptr_data->_ptr); continue;
|
||||
case 4: cgGLSetParameterArray4d(p, 0, _ptr._dim[0], (double*)ptr_data->_ptr); continue;
|
||||
switch (spec._dim[2]) {
|
||||
case 1: cgGLSetParameterArray1d(p, 0, spec._dim[0], (double*)ptr_data->_ptr); continue;
|
||||
case 2: cgGLSetParameterArray2d(p, 0, spec._dim[0], (double*)ptr_data->_ptr); continue;
|
||||
case 3: cgGLSetParameterArray3d(p, 0, spec._dim[0], (double*)ptr_data->_ptr); continue;
|
||||
case 4: cgGLSetParameterArray4d(p, 0, spec._dim[0], (double*)ptr_data->_ptr); continue;
|
||||
default:
|
||||
nassertd(_ptr._dim[2] > 0 && _ptr._dim[2] <= 4) continue;
|
||||
nassertd(spec._dim[2] > 0 && spec._dim[2] <= 4) continue;
|
||||
}
|
||||
continue;
|
||||
case Shader::SAC_matrix:
|
||||
cgGLSetMatrixParameterArraydc(p, 0, _ptr._dim[0], (double*)ptr_data->_ptr);
|
||||
cgGLSetMatrixParameterArraydc(p, 0, spec._dim[0], (double*)ptr_data->_ptr);
|
||||
continue;
|
||||
default:
|
||||
nassertd(false) continue;
|
||||
@ -559,12 +636,12 @@ issue_parameters(int altered) {
|
||||
continue;
|
||||
|
||||
case Shader::SPT_int:
|
||||
switch(_ptr._info._class) {
|
||||
switch (spec._info._class) {
|
||||
case Shader::SAC_scalar:
|
||||
cgSetParameter1iv(p, (int*)ptr_data->_ptr);
|
||||
continue;
|
||||
case Shader::SAC_vector:
|
||||
switch(_ptr._info._type) {
|
||||
switch (spec._info._type) {
|
||||
case Shader::SAT_vec1: cgSetParameter1iv(p, (int*)ptr_data->_ptr); continue;
|
||||
case Shader::SAT_vec2: cgSetParameter2iv(p, (int*)ptr_data->_ptr); continue;
|
||||
case Shader::SAT_vec3: cgSetParameter3iv(p, (int*)ptr_data->_ptr); continue;
|
||||
@ -576,21 +653,27 @@ issue_parameters(int altered) {
|
||||
nassertd(false) continue;
|
||||
}
|
||||
default:
|
||||
GLCAT.error() << _ptr._id._name << ":" << "unrecognized parameter type\n";
|
||||
GLCAT.error() << spec._id._name << ":" << "unrecognized parameter type\n";
|
||||
release_resources();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i<(int)_shader->_mat_spec.size(); i++) {
|
||||
if (altered & (_shader->_mat_spec[i]._dep[0] | _shader->_mat_spec[i]._dep[1])) {
|
||||
const LMatrix4 *val = _glgsg->fetch_specified_value(_shader->_mat_spec[i], altered);
|
||||
if (altered & _shader->_mat_deps) {
|
||||
for (int i = 0; i < (int)_shader->_mat_spec.size(); ++i) {
|
||||
Shader::ShaderMatSpec &spec = _shader->_mat_spec[i];
|
||||
|
||||
if ((altered & (spec._dep[0] | spec._dep[1])) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const LMatrix4 *val = _glgsg->fetch_specified_value(spec, altered);
|
||||
if (!val) continue;
|
||||
const PN_stdfloat *data = val->get_data();
|
||||
|
||||
CGparameter p = _cg_parameter_map[_shader->_mat_spec[i]._id._seqno];
|
||||
switch (_shader->_mat_spec[i]._piece) {
|
||||
CGparameter p = _cg_parameter_map[spec._id._seqno];
|
||||
switch (spec._piece) {
|
||||
case Shader::SMP_whole: GLfc(cgGLSetMatrixParameter)(p, data); continue;
|
||||
case Shader::SMP_transpose: GLfr(cgGLSetMatrixParameter)(p, data); continue;
|
||||
case Shader::SMP_col0: GLf(cgGLSetParameter4)(p, data[0], data[4], data[ 8], data[12]); continue;
|
||||
@ -981,9 +1064,9 @@ disable_shader_texture_bindings() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(CgShaderContext)::
|
||||
update_shader_texture_bindings(ShaderContext *prev) {
|
||||
if (prev) {
|
||||
prev->disable_shader_texture_bindings();
|
||||
}
|
||||
//if (prev) {
|
||||
// prev->disable_shader_texture_bindings();
|
||||
//}
|
||||
|
||||
if (!valid()) {
|
||||
return;
|
||||
|
@ -38,19 +38,23 @@ public:
|
||||
ALLOC_DELETED_CHAIN(CLP(CgShaderContext));
|
||||
|
||||
INLINE bool valid(void);
|
||||
void bind(bool reissue_parameters = true);
|
||||
void unbind();
|
||||
void issue_parameters(int altered);
|
||||
void bind() OVERRIDE;
|
||||
void unbind() OVERRIDE;
|
||||
|
||||
void set_state_and_transform(const RenderState *state,
|
||||
const TransformState *modelview_transform,
|
||||
const TransformState *projection_transform);
|
||||
|
||||
void issue_parameters(int altered) OVERRIDE;
|
||||
void update_transform_table(const TransformTable *table);
|
||||
void update_slider_table(const SliderTable *table);
|
||||
void disable_shader_vertex_arrays();
|
||||
bool update_shader_vertex_arrays(ShaderContext *prev, bool force);
|
||||
void disable_shader_texture_bindings();
|
||||
void update_shader_texture_bindings(ShaderContext *prev);
|
||||
void disable_shader_vertex_arrays() OVERRIDE;
|
||||
bool update_shader_vertex_arrays(ShaderContext *prev, bool force) OVERRIDE;
|
||||
void disable_shader_texture_bindings() OVERRIDE;
|
||||
void update_shader_texture_bindings(ShaderContext *prev) OVERRIDE;
|
||||
|
||||
INLINE bool uses_standard_vertex_arrays(void);
|
||||
INLINE bool uses_custom_vertex_arrays(void);
|
||||
INLINE bool uses_custom_texture_bindings(void);
|
||||
|
||||
// Special values for location to indicate conventional attrib slots.
|
||||
enum ConventionalAttrib {
|
||||
@ -74,6 +78,11 @@ private:
|
||||
|
||||
pvector<CGparameter> _cg_parameter_map;
|
||||
|
||||
CPT(RenderState) _state_rs;
|
||||
CPT(TransformState) _modelview_transform;
|
||||
CPT(TransformState) _projection_transform;
|
||||
GLint _frame_number;
|
||||
|
||||
CLP(GraphicsStateGuardian) *_glgsg;
|
||||
|
||||
bool _has_divisor;
|
||||
|
@ -307,7 +307,7 @@ rebuild_bitplanes() {
|
||||
RenderTexturePlane plane = rt._plane;
|
||||
Texture *tex = rt._texture;
|
||||
|
||||
if (rtm_mode == RTM_bind_layered) {
|
||||
if (rtm_mode == RTM_bind_layered && glgsg->_supports_geometry_shaders) {
|
||||
if (tex->get_z_size() != _rb_size_z) {
|
||||
GLCAT.warning()
|
||||
<< "All textures attached to layered FBO should have the same layer count!\n";
|
||||
|
@ -1527,11 +1527,15 @@ reset() {
|
||||
_glVertexAttribLPointer = NULL;
|
||||
#endif
|
||||
|
||||
#ifndef OPENGLES_1
|
||||
// We need to have a default shader to apply in case
|
||||
// something didn't happen to have a shader applied, or
|
||||
// if it failed to compile. This default shader just outputs
|
||||
// a red color, indicating that something went wrong.
|
||||
#ifndef SUPPORT_FIXED_FUNCTION
|
||||
if (_default_shader == NULL) {
|
||||
_default_shader = Shader::make(Shader::SL_GLSL, default_vshader, default_fshader);
|
||||
}
|
||||
#elif !defined(OPENGLES)
|
||||
if (_default_shader == NULL && core_profile) {
|
||||
_default_shader = Shader::make(Shader::SL_GLSL, default_vshader, default_fshader);
|
||||
}
|
||||
@ -2926,6 +2930,11 @@ clear_before_callback() {
|
||||
#ifndef OPENGLES
|
||||
if (_supports_sampler_objects) {
|
||||
_glBindSampler(0, 0);
|
||||
|
||||
if (GLCAT.is_spam()) {
|
||||
GLCAT.spam()
|
||||
<< "glBindSampler(0, 0)\n";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -5548,6 +5557,11 @@ framebuffer_copy_to_texture(Texture *tex, int view, int z,
|
||||
if (new_image && gtc->_immutable) {
|
||||
gtc->reset_data();
|
||||
glBindTexture(target, gtc->_index);
|
||||
|
||||
if (GLCAT.is_spam()) {
|
||||
GLCAT.spam()
|
||||
<< "glBindTexture(0x" << hex << target << dec << ", " << gtc->_index << ")\n";
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef OPENGLES
|
||||
@ -5844,12 +5858,6 @@ do_issue_transform() {
|
||||
#endif
|
||||
_transform_stale = false;
|
||||
|
||||
#ifndef OPENGLES_1
|
||||
if (_current_shader_context) {
|
||||
_current_shader_context->issue_parameters(Shader::SSD_transform);
|
||||
}
|
||||
#endif
|
||||
|
||||
report_my_gl_errors();
|
||||
}
|
||||
|
||||
@ -5885,9 +5893,9 @@ do_issue_shade_model() {
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
do_issue_shader(bool state_has_changed) {
|
||||
do_issue_shader() {
|
||||
ShaderContext *context = 0;
|
||||
Shader *shader = (Shader *)(_target_shader->get_shader());
|
||||
Shader *shader = (Shader *)_target_shader->get_shader();
|
||||
|
||||
#ifndef SUPPORT_FIXED_FUNCTION
|
||||
// If we don't have a shader, apply the default shader.
|
||||
@ -5919,18 +5927,13 @@ do_issue_shader(bool state_has_changed) {
|
||||
if (context != _current_shader_context) {
|
||||
// Use a completely different shader than before.
|
||||
// Unbind old shader, bind the new one.
|
||||
if (_current_shader_context != 0) {
|
||||
if (_current_shader_context != NULL &&
|
||||
_current_shader->get_language() != shader->get_language()) {
|
||||
_current_shader_context->unbind();
|
||||
}
|
||||
context->bind();
|
||||
_current_shader = shader;
|
||||
_current_shader_context = context;
|
||||
context->issue_parameters(Shader::SSD_shaderinputs);
|
||||
} else {
|
||||
if (state_has_changed) {
|
||||
// Use the same shader as before, but with new input arguments.
|
||||
context->issue_parameters(Shader::SSD_shaderinputs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -6410,6 +6413,11 @@ do_issue_blending() {
|
||||
_glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFunc(GL_ZERO, GL_ONE);
|
||||
}
|
||||
|
||||
if (GLCAT.is_spam()) {
|
||||
GLCAT.spam() << "glBlendEquation(GL_FUNC_ADD)\n";
|
||||
GLCAT.spam() << "glBlendFunc(GL_ZERO, GL_ONE)\n";
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
set_color_write_mask(color_channels);
|
||||
@ -6433,16 +6441,23 @@ do_issue_blending() {
|
||||
enable_blend(true);
|
||||
_glBlendEquation(get_blend_equation_type(color_blend_mode));
|
||||
glBlendFunc(get_blend_func(color_blend->get_operand_a()),
|
||||
get_blend_func(color_blend->get_operand_b()));
|
||||
get_blend_func(color_blend->get_operand_b()));
|
||||
|
||||
LColor c;
|
||||
if (_color_blend_involves_color_scale) {
|
||||
// Apply the current color scale to the blend mode.
|
||||
_glBlendColor(_current_color_scale[0], _current_color_scale[1],
|
||||
_current_color_scale[2], _current_color_scale[3]);
|
||||
|
||||
c = _current_color_scale;
|
||||
} else {
|
||||
LColor c = color_blend->get_color();
|
||||
_glBlendColor(c[0], c[1], c[2], c[3]);
|
||||
c = color_blend->get_color();
|
||||
}
|
||||
|
||||
_glBlendColor(c[0], c[1], c[2], c[3]);
|
||||
|
||||
if (GLCAT.is_spam()) {
|
||||
GLCAT.spam() << "glBlendEquation(" << color_blend_mode << ")\n";
|
||||
GLCAT.spam() << "glBlendFunc(" << color_blend->get_operand_a()
|
||||
<< color_blend->get_operand_b() << ")\n";
|
||||
GLCAT.spam() << "glBlendColor(" << c << ")\n";
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -6460,6 +6475,11 @@ do_issue_blending() {
|
||||
enable_blend(true);
|
||||
_glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
if (GLCAT.is_spam()) {
|
||||
GLCAT.spam() << "glBlendEquation(GL_FUNC_ADD)\n";
|
||||
GLCAT.spam() << "glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)\n";
|
||||
}
|
||||
return;
|
||||
|
||||
case TransparencyAttrib::M_multisample:
|
||||
@ -6489,6 +6509,11 @@ do_issue_blending() {
|
||||
enable_blend(true);
|
||||
_glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
if (GLCAT.is_spam()) {
|
||||
GLCAT.spam() << "glBlendEquation(GL_FUNC_ADD)\n";
|
||||
GLCAT.spam() << "glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)\n";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -9224,10 +9249,27 @@ set_state_and_transform(const RenderState *target,
|
||||
}
|
||||
_target_rs = target;
|
||||
|
||||
#ifndef OPENGLES_1
|
||||
_target_shader = (const ShaderAttrib *)
|
||||
_target_rs->get_attrib_def(ShaderAttrib::get_class_slot());
|
||||
#ifndef OPENGLES_1
|
||||
_instance_count = _target_shader->get_instance_count();
|
||||
|
||||
if (_target_shader != _state_shader) {
|
||||
//PStatGPUTimer timer(this, _draw_set_state_shader_pcollector);
|
||||
do_issue_shader();
|
||||
_state_shader = _target_shader;
|
||||
_state_mask.clear_bit(TextureAttrib::get_class_slot());
|
||||
}
|
||||
#ifndef SUPPORT_FIXED_FUNCTION
|
||||
else { // In the case of OpenGL ES 2.x, we need to glUseShader before we draw anything.
|
||||
do_issue_shader();
|
||||
_state_mask.clear_bit(TextureAttrib::get_class_slot());
|
||||
}
|
||||
#endif
|
||||
|
||||
if (_current_shader_context != NULL) {
|
||||
_current_shader_context->set_state_and_transform(target, transform, _projection_mat);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
@ -9256,11 +9298,6 @@ set_state_and_transform(const RenderState *target,
|
||||
//PStatGPUTimer timer(this, _draw_set_state_clip_plane_pcollector);
|
||||
do_issue_clip_plane();
|
||||
_state_mask.set_bit(clip_plane_slot);
|
||||
#ifndef OPENGLES_1
|
||||
if (_current_shader_context) {
|
||||
_current_shader_context->issue_parameters(Shader::SSD_clip_planes);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int color_slot = ColorAttrib::get_class_slot();
|
||||
@ -9274,12 +9311,6 @@ set_state_and_transform(const RenderState *target,
|
||||
do_issue_color_scale();
|
||||
_state_mask.set_bit(color_slot);
|
||||
_state_mask.set_bit(color_scale_slot);
|
||||
#ifndef OPENGLES_1
|
||||
if (_current_shader_context) {
|
||||
_current_shader_context->issue_parameters(Shader::SSD_color);
|
||||
_current_shader_context->issue_parameters(Shader::SSD_colorscale);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int cull_face_slot = CullFaceAttrib::get_class_slot();
|
||||
@ -9360,20 +9391,6 @@ set_state_and_transform(const RenderState *target,
|
||||
_state_mask.set_bit(color_blend_slot);
|
||||
}
|
||||
|
||||
if (_target_shader != _state_shader) {
|
||||
//PStatGPUTimer timer(this, _draw_set_state_shader_pcollector);
|
||||
#ifndef OPENGLES_1
|
||||
do_issue_shader(true);
|
||||
#endif
|
||||
_state_shader = _target_shader;
|
||||
_state_mask.clear_bit(TextureAttrib::get_class_slot());
|
||||
}
|
||||
#ifndef SUPPORT_FIXED_FUNCTION
|
||||
else { // In the case of OpenGL ES 2.x, we need to glUseShader before we draw anything.
|
||||
do_issue_shader(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
int texture_slot = TextureAttrib::get_class_slot();
|
||||
if (_target_rs->get_attrib(texture_slot) != _state_rs->get_attrib(texture_slot) ||
|
||||
!_state_mask.get_bit(texture_slot)) {
|
||||
@ -9441,11 +9458,6 @@ set_state_and_transform(const RenderState *target,
|
||||
do_issue_material();
|
||||
#endif
|
||||
_state_mask.set_bit(material_slot);
|
||||
#ifndef OPENGLES_1
|
||||
if (_current_shader_context) {
|
||||
_current_shader_context->issue_parameters(Shader::SSD_material);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int light_slot = LightAttrib::get_class_slot();
|
||||
@ -9456,11 +9468,6 @@ set_state_and_transform(const RenderState *target,
|
||||
do_issue_light();
|
||||
#endif
|
||||
_state_mask.set_bit(light_slot);
|
||||
#ifndef OPENGLES_1
|
||||
if (_current_shader_context) {
|
||||
_current_shader_context->issue_parameters(Shader::SSD_light);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int stencil_slot = StencilAttrib::get_class_slot();
|
||||
@ -9479,11 +9486,6 @@ set_state_and_transform(const RenderState *target,
|
||||
do_issue_fog();
|
||||
#endif
|
||||
_state_mask.set_bit(fog_slot);
|
||||
#ifndef OPENGLES_1
|
||||
if (_current_shader_context) {
|
||||
_current_shader_context->issue_parameters(Shader::SSD_fog);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int scissor_slot = ScissorAttrib::get_class_slot();
|
||||
@ -9528,7 +9530,7 @@ do_issue_texture() {
|
||||
#ifdef OPENGLES_1
|
||||
update_standard_texture_bindings();
|
||||
#else
|
||||
if (_current_shader_context == 0 || !_current_shader_context->uses_custom_texture_bindings()) {
|
||||
if (_current_shader_context == 0) {
|
||||
// No shader, or a non-Cg shader.
|
||||
if (_texture_binding_shader_context != 0) {
|
||||
_texture_binding_shader_context->disable_shader_texture_bindings();
|
||||
@ -9909,9 +9911,9 @@ update_show_usage_texture_bindings(int show_stage_index) {
|
||||
|
||||
UsageTextureKey key(texture->get_x_size(), texture->get_y_size());
|
||||
UsageTextures::iterator ui = _usage_textures.find(key);
|
||||
GLuint index;
|
||||
if (ui == _usage_textures.end()) {
|
||||
// Need to create a new texture for this size.
|
||||
GLuint index;
|
||||
glGenTextures(1, &index);
|
||||
glBindTexture(GL_TEXTURE_2D, index);
|
||||
//TODO: this could be a lot simpler with glTexStorage2D
|
||||
@ -9921,10 +9923,15 @@ update_show_usage_texture_bindings(int show_stage_index) {
|
||||
|
||||
} else {
|
||||
// Just bind the previously-created texture.
|
||||
GLuint index = (*ui).second;
|
||||
index = (*ui).second;
|
||||
glBindTexture(GL_TEXTURE_2D, index);
|
||||
}
|
||||
|
||||
if (GLCAT.is_spam()) {
|
||||
GLCAT.spam()
|
||||
<< "glBindTexture(GL_TEXTURE_2D, " << index << ")\n";
|
||||
}
|
||||
|
||||
//TODO: glBindSampler(0) ?
|
||||
}
|
||||
|
||||
@ -10468,9 +10475,14 @@ specify_texture(CLP(TextureContext) *gtc, const SamplerState &sampler) {
|
||||
#endif
|
||||
|
||||
#ifndef OPENGLES
|
||||
glTexParameterf(target, GL_TEXTURE_MIN_LOD, sampler.get_min_lod());
|
||||
glTexParameterf(target, GL_TEXTURE_MAX_LOD, sampler.get_max_lod());
|
||||
glTexParameterf(target, GL_TEXTURE_LOD_BIAS, sampler.get_lod_bias());
|
||||
if (is_at_least_gl_version(1, 2)) {
|
||||
glTexParameterf(target, GL_TEXTURE_MIN_LOD, sampler.get_min_lod());
|
||||
glTexParameterf(target, GL_TEXTURE_MAX_LOD, sampler.get_max_lod());
|
||||
|
||||
if (is_at_least_gl_version(1, 4)) {
|
||||
glTexParameterf(target, GL_TEXTURE_LOD_BIAS, sampler.get_lod_bias());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
report_my_gl_errors();
|
||||
@ -10505,7 +10517,12 @@ apply_texture(CLP(TextureContext) *gtc) {
|
||||
gtc->reset_data();
|
||||
gtc->_target = target;
|
||||
}
|
||||
|
||||
glBindTexture(target, gtc->_index);
|
||||
if (GLCAT.is_spam()) {
|
||||
GLCAT.spam()
|
||||
<< "glBindTexture(0x" << hex << target << dec << ", " << gtc->_index << ")\n";
|
||||
}
|
||||
|
||||
report_my_gl_errors();
|
||||
return true;
|
||||
@ -10537,8 +10554,8 @@ apply_sampler(GLuint unit, const SamplerState &sampler, CLP(TextureContext) *gtc
|
||||
_glBindSampler(unit, gsc->_index);
|
||||
|
||||
if (GLCAT.is_spam()) {
|
||||
GLCAT.spam()
|
||||
<< "bind " << unit << " " << sampler << "\n";
|
||||
GLCAT.spam() << "glBindSampler(" << unit << ", "
|
||||
<< gsc->_index << "): " << sampler << "\n";
|
||||
}
|
||||
|
||||
} else
|
||||
@ -10791,6 +10808,11 @@ upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) {
|
||||
GLCAT.warning() << "Attempt to modify texture with immutable storage, recreating texture.\n";
|
||||
gtc->reset_data();
|
||||
glBindTexture(target, gtc->_index);
|
||||
|
||||
if (GLCAT.is_spam()) {
|
||||
GLCAT.spam()
|
||||
<< "glBindTexture(0x" << hex << target << dec << ", " << gtc->_index << ")\n";
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef OPENGLES
|
||||
@ -11045,6 +11067,8 @@ upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) {
|
||||
gtc->update_data_size_bytes(get_texture_memory_size(tex));
|
||||
}
|
||||
|
||||
nassertr(gtc->_has_storage, false);
|
||||
|
||||
if (tex->get_post_load_store_cache()) {
|
||||
tex->set_post_load_store_cache(false);
|
||||
// OK, get the RAM image, and save it in a BamCache record.
|
||||
@ -11752,6 +11776,10 @@ do_extract_texture_data(CLP(TextureContext) *gtc) {
|
||||
#endif
|
||||
|
||||
glBindTexture(target, gtc->_index);
|
||||
if (GLCAT.is_spam()) {
|
||||
GLCAT.spam()
|
||||
<< "glBindTexture(0x" << hex << target << dec << ", " << gtc->_index << ")\n";
|
||||
}
|
||||
|
||||
Texture *tex = gtc->get_texture();
|
||||
|
||||
|
@ -399,7 +399,7 @@ protected:
|
||||
void do_issue_depth_offset();
|
||||
void do_issue_shade_model();
|
||||
#ifndef OPENGLES_1
|
||||
void do_issue_shader(bool state_has_changed = false);
|
||||
void do_issue_shader();
|
||||
#endif
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
void do_issue_material();
|
||||
@ -462,8 +462,10 @@ protected:
|
||||
INLINE void enable_stencil_test(bool val);
|
||||
INLINE void enable_blend(bool val);
|
||||
INLINE void enable_depth_test(bool val);
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
INLINE void enable_fog(bool val);
|
||||
INLINE void enable_alpha_test(bool val);
|
||||
#endif
|
||||
INLINE void enable_polygon_offset(bool val);
|
||||
|
||||
INLINE void set_color_write_mask(int mask);
|
||||
|
@ -55,13 +55,3 @@ INLINE bool CLP(ShaderContext)::
|
||||
uses_custom_vertex_arrays() {
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLShaderContext::uses_custom_texture_bindings
|
||||
// Access: Public
|
||||
// Description: Always true, for now.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool CLP(ShaderContext)::
|
||||
uses_custom_texture_bindings() {
|
||||
return true;
|
||||
}
|
||||
|
@ -18,17 +18,15 @@
|
||||
|
||||
#include "pStatGPUTimer.h"
|
||||
|
||||
TypeHandle CLP(ShaderContext)::_type_handle;
|
||||
#include "colorAttrib.h"
|
||||
#include "colorScaleAttrib.h"
|
||||
#include "materialAttrib.h"
|
||||
#include "shaderAttrib.h"
|
||||
#include "fogAttrib.h"
|
||||
#include "lightAttrib.h"
|
||||
#include "clipPlaneAttrib.h"
|
||||
|
||||
#ifndef GL_GEOMETRY_SHADER_EXT
|
||||
#define GL_GEOMETRY_SHADER_EXT 0x8DD9
|
||||
#endif
|
||||
#ifndef GL_GEOMETRY_VERTICES_OUT_EXT
|
||||
#define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA
|
||||
#endif
|
||||
#ifndef GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT
|
||||
#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0
|
||||
#endif
|
||||
TypeHandle CLP(ShaderContext)::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLShaderContext::ParseAndSetShaderUniformVars
|
||||
@ -228,6 +226,7 @@ parse_and_set_short_hand_shader_vars(Shader::ShaderArgId &arg_id, GLenum param_t
|
||||
|
||||
objShader->cp_optimize_mat_spec(bind);
|
||||
objShader->_mat_spec.push_back(bind);
|
||||
objShader->_mat_deps |= bind._dep[0] | bind._dep[1];
|
||||
|
||||
if (param_size > 1) {
|
||||
// We support arrays of rows and arrays of columns, so we can
|
||||
@ -338,8 +337,14 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext
|
||||
reflect_attribute(i, name_buffer, name_buflen);
|
||||
}
|
||||
|
||||
_glgsg->_glUseProgram(0);
|
||||
_glgsg->report_my_gl_errors();
|
||||
|
||||
// Restore the active shader.
|
||||
if (_glgsg->_current_shader_context == NULL) {
|
||||
_glgsg->_glUseProgram(0);
|
||||
} else {
|
||||
_glgsg->_current_shader_context->bind();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -715,8 +720,6 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
|
||||
}
|
||||
bind._arg[0] = NULL;
|
||||
bind._arg[1] = NULL;
|
||||
bind._dep[0] = Shader::SSD_general | Shader::SSD_transform;
|
||||
bind._dep[1] = Shader::SSD_general | Shader::SSD_transform;
|
||||
|
||||
if (matrix_name == "ModelViewProjectionMatrix") {
|
||||
if (inverse) {
|
||||
@ -802,7 +805,9 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
|
||||
GLCAT.error() << "Unrecognized uniform matrix name '" << matrix_name << "'!\n";
|
||||
return;
|
||||
}
|
||||
_shader->cp_optimize_mat_spec(bind);
|
||||
_shader->_mat_spec.push_back(bind);
|
||||
_shader->_mat_deps |= bind._dep[0] | bind._dep[1];
|
||||
return;
|
||||
}
|
||||
if (size > 7 && noprefix.substr(0, 7) == "Texture") {
|
||||
@ -846,6 +851,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
|
||||
}
|
||||
bind._piece = Shader::SMP_row0;
|
||||
_shader->_mat_spec.push_back(bind);
|
||||
_shader->_mat_deps |= bind._dep[0];
|
||||
return;
|
||||
|
||||
} else if (noprefix == "Material.diffuse") {
|
||||
@ -855,6 +861,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
|
||||
}
|
||||
bind._piece = Shader::SMP_row1;
|
||||
_shader->_mat_spec.push_back(bind);
|
||||
_shader->_mat_deps |= bind._dep[0];
|
||||
return;
|
||||
|
||||
} else if (noprefix == "Material.emission") {
|
||||
@ -864,6 +871,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
|
||||
}
|
||||
bind._piece = Shader::SMP_row2;
|
||||
_shader->_mat_spec.push_back(bind);
|
||||
_shader->_mat_deps |= bind._dep[0];
|
||||
return;
|
||||
|
||||
} else if (noprefix == "Material.specular") {
|
||||
@ -873,6 +881,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
|
||||
}
|
||||
bind._piece = Shader::SMP_row3x3;
|
||||
_shader->_mat_spec.push_back(bind);
|
||||
_shader->_mat_deps |= bind._dep[0];
|
||||
return;
|
||||
|
||||
} else if (noprefix == "Material.shininess") {
|
||||
@ -882,6 +891,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
|
||||
}
|
||||
bind._piece = Shader::SMP_cell15;
|
||||
_shader->_mat_spec.push_back(bind);
|
||||
_shader->_mat_deps |= bind._dep[0];
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -906,6 +916,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
|
||||
return;
|
||||
}
|
||||
_shader->_mat_spec.push_back(bind);
|
||||
_shader->_mat_deps |= bind._dep[0];
|
||||
return;
|
||||
}
|
||||
if (noprefix == "Color") {
|
||||
@ -929,6 +940,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
|
||||
return;
|
||||
}
|
||||
_shader->_mat_spec.push_back(bind);
|
||||
_shader->_mat_deps |= bind._dep[0];
|
||||
return;
|
||||
}
|
||||
if (noprefix == "ClipPlane") {
|
||||
@ -951,6 +963,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
|
||||
bind._arg[1] = NULL;
|
||||
bind._dep[1] = Shader::SSD_NONE;
|
||||
_shader->_mat_spec.push_back(bind);
|
||||
_shader->_mat_deps |= bind._dep[0];
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -975,6 +988,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
|
||||
return;
|
||||
}
|
||||
_shader->_mat_spec.push_back(bind);
|
||||
_shader->_mat_deps |= bind._dep[0];
|
||||
return;
|
||||
}
|
||||
if (noprefix == "TransformTable") {
|
||||
@ -1016,8 +1030,9 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
|
||||
bind._part[0] = Shader::SMO_world_to_view;
|
||||
bind._part[1] = Shader::SMO_view_to_apiview;
|
||||
bind._dep[0] = Shader::SSD_general | Shader::SSD_transform;
|
||||
bind._dep[1] = Shader::SSD_general | Shader::SSD_transform;
|
||||
bind._dep[1] = Shader::SSD_general;
|
||||
_shader->_mat_spec.push_back(bind);
|
||||
_shader->_mat_deps |= bind._dep[0] | bind._dep[1];
|
||||
return;
|
||||
|
||||
} else if (noprefix == "InverseViewMatrix" || noprefix == "ViewMatrixInverse") {
|
||||
@ -1025,9 +1040,10 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
|
||||
bind._func = Shader::SMF_compose;
|
||||
bind._part[0] = Shader::SMO_apiview_to_view;
|
||||
bind._part[1] = Shader::SMO_view_to_world;
|
||||
bind._dep[0] = Shader::SSD_general | Shader::SSD_transform;
|
||||
bind._dep[0] = Shader::SSD_general;
|
||||
bind._dep[1] = Shader::SSD_general | Shader::SSD_transform;
|
||||
_shader->_mat_spec.push_back(bind);
|
||||
_shader->_mat_deps |= bind._dep[0] | bind._dep[1];
|
||||
return;
|
||||
|
||||
} else if (noprefix == "FrameTime") {
|
||||
@ -1035,9 +1051,10 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
|
||||
bind._func = Shader::SMF_first;
|
||||
bind._part[0] = Shader::SMO_frame_time;
|
||||
bind._part[1] = Shader::SMO_identity;
|
||||
bind._dep[0] = Shader::SSD_general;
|
||||
bind._dep[0] = Shader::SSD_general | Shader::SSD_frame;
|
||||
bind._dep[1] = Shader::SSD_NONE;
|
||||
_shader->_mat_spec.push_back(bind);
|
||||
_shader->_mat_deps |= bind._dep[0] | bind._dep[1];
|
||||
return;
|
||||
|
||||
} else if (noprefix == "DeltaFrameTime") {
|
||||
@ -1045,9 +1062,10 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
|
||||
bind._func = Shader::SMF_first;
|
||||
bind._part[0] = Shader::SMO_frame_delta;
|
||||
bind._part[1] = Shader::SMO_identity;
|
||||
bind._dep[0] = Shader::SSD_general;
|
||||
bind._dep[0] = Shader::SSD_general | Shader::SSD_frame;
|
||||
bind._dep[1] = Shader::SSD_NONE;
|
||||
_shader->_mat_spec.push_back(bind);
|
||||
_shader->_mat_deps |= bind._dep[0] | bind._dep[1];
|
||||
return;
|
||||
|
||||
} else if (noprefix == "FrameNumber") {
|
||||
@ -1124,11 +1142,12 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
|
||||
bind._func = Shader::SMF_first;
|
||||
bind._part[0] = Shader::SMO_mat_constant_x;
|
||||
bind._arg[0] = InternalName::make(param_name);
|
||||
bind._dep[0] = Shader::SSD_general | Shader::SSD_shaderinputs;
|
||||
bind._dep[0] = Shader::SSD_general | Shader::SSD_shaderinputs | Shader::SSD_frame;
|
||||
bind._part[1] = Shader::SMO_identity;
|
||||
bind._arg[1] = NULL;
|
||||
bind._dep[1] = Shader::SSD_NONE;
|
||||
_shader->_mat_spec.push_back(bind);
|
||||
_shader->_mat_deps |= bind._dep[0];
|
||||
return;
|
||||
}
|
||||
case GL_FLOAT_MAT4: {
|
||||
@ -1138,11 +1157,12 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
|
||||
bind._func = Shader::SMF_first;
|
||||
bind._part[0] = Shader::SMO_mat_constant_x;
|
||||
bind._arg[0] = InternalName::make(param_name);
|
||||
bind._dep[0] = Shader::SSD_general | Shader::SSD_shaderinputs;
|
||||
bind._dep[0] = Shader::SSD_general | Shader::SSD_shaderinputs | Shader::SSD_frame;
|
||||
bind._part[1] = Shader::SMO_identity;
|
||||
bind._arg[1] = NULL;
|
||||
bind._dep[1] = Shader::SSD_NONE;
|
||||
_shader->_mat_spec.push_back(bind);
|
||||
_shader->_mat_deps |= bind._dep[0];
|
||||
return;
|
||||
}
|
||||
case GL_FLOAT:
|
||||
@ -1172,11 +1192,12 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
|
||||
bind._func = Shader::SMF_first;
|
||||
bind._part[0] = Shader::SMO_vec_constant_x_attrib;
|
||||
bind._arg[0] = iname;
|
||||
bind._dep[0] = Shader::SSD_general | Shader::SSD_shaderinputs;
|
||||
bind._dep[0] = Shader::SSD_general | Shader::SSD_shaderinputs | Shader::SSD_frame;
|
||||
bind._part[1] = Shader::SMO_identity;
|
||||
bind._arg[1] = NULL;
|
||||
bind._dep[1] = Shader::SSD_NONE;
|
||||
_shader->_mat_spec.push_back(bind);
|
||||
_shader->_mat_deps |= bind._dep[0];
|
||||
return;
|
||||
} // else fall through
|
||||
}
|
||||
@ -1228,7 +1249,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
|
||||
}
|
||||
bind._arg = InternalName::make(param_name);
|
||||
bind._dim[0] = 1;
|
||||
bind._dep[0] = Shader::SSD_general | Shader::SSD_shaderinputs;
|
||||
bind._dep[0] = Shader::SSD_general | Shader::SSD_shaderinputs | Shader::SSD_frame;
|
||||
bind._dep[1] = Shader::SSD_NONE;
|
||||
_shader->_ptr_spec.push_back(bind);
|
||||
return;
|
||||
@ -1335,7 +1356,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
|
||||
}
|
||||
bind._arg = InternalName::make(param_name);
|
||||
bind._dim[0] = param_size;
|
||||
bind._dep[0] = Shader::SSD_general | Shader::SSD_shaderinputs;
|
||||
bind._dep[0] = Shader::SSD_general | Shader::SSD_shaderinputs | Shader::SSD_frame;
|
||||
bind._dep[1] = Shader::SSD_NONE;
|
||||
_shader->_ptr_spec.push_back(bind);
|
||||
return;
|
||||
@ -1507,23 +1528,22 @@ release_resources() {
|
||||
// input parameters.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(ShaderContext)::
|
||||
bind(bool reissue_parameters) {
|
||||
// GLSL shaders need to be bound before passing parameters.
|
||||
if (!_shader->get_error_flag()) {
|
||||
_glgsg->_glUseProgram(_glsl_program);
|
||||
}
|
||||
|
||||
if (reissue_parameters) {
|
||||
// Pass in k-parameters and transform-parameters
|
||||
issue_parameters(Shader::SSD_general);
|
||||
}
|
||||
|
||||
bind() {
|
||||
if (!_validated) {
|
||||
_glgsg->_glValidateProgram(_glsl_program);
|
||||
glsl_report_program_errors(_glsl_program, false);
|
||||
_validated = true;
|
||||
}
|
||||
|
||||
if (!_shader->get_error_flag()) {
|
||||
_glgsg->_glUseProgram(_glsl_program);
|
||||
}
|
||||
|
||||
if (GLCAT.is_spam()) {
|
||||
GLCAT.spam() << "glUseProgram(" << _glsl_program << "): "
|
||||
<< _shader->get_filename() << "\n";
|
||||
}
|
||||
|
||||
_glgsg->report_my_gl_errors();
|
||||
}
|
||||
|
||||
@ -1534,10 +1554,92 @@ bind(bool reissue_parameters) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(ShaderContext)::
|
||||
unbind() {
|
||||
if (GLCAT.is_spam()) {
|
||||
GLCAT.spam() << "glUseProgram(0)\n";
|
||||
}
|
||||
|
||||
_glgsg->_glUseProgram(0);
|
||||
_glgsg->report_my_gl_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLShaderContext::set_state_and_transform
|
||||
// Access: Public
|
||||
// Description: This function gets called whenever the RenderState
|
||||
// or TransformState has changed, but the Shader
|
||||
// itself has not changed. It loads new values into the
|
||||
// shader's parameters.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(ShaderContext)::
|
||||
set_state_and_transform(const RenderState *target_rs,
|
||||
const TransformState *modelview_transform,
|
||||
const TransformState *projection_transform) {
|
||||
|
||||
// Find out which state properties have changed.
|
||||
int altered = 0;
|
||||
|
||||
if (_modelview_transform != modelview_transform) {
|
||||
_modelview_transform = modelview_transform;
|
||||
altered |= Shader::SSD_transform;
|
||||
}
|
||||
if (_projection_transform != projection_transform) {
|
||||
_projection_transform = projection_transform;
|
||||
altered |= Shader::SSD_projection;
|
||||
}
|
||||
|
||||
if (_state_rs != target_rs) {
|
||||
if (_state_rs == NULL) {
|
||||
// We haven't set any state yet.
|
||||
altered |= Shader::SSD_general;
|
||||
} else {
|
||||
if (_state_rs->get_attrib(ColorAttrib::get_class_slot()) !=
|
||||
target_rs->get_attrib(ColorAttrib::get_class_slot())) {
|
||||
altered |= Shader::SSD_color;
|
||||
}
|
||||
if (_state_rs->get_attrib(ColorScaleAttrib::get_class_slot()) !=
|
||||
target_rs->get_attrib(ColorScaleAttrib::get_class_slot())) {
|
||||
altered |= Shader::SSD_colorscale;
|
||||
}
|
||||
if (_state_rs->get_attrib(MaterialAttrib::get_class_slot()) !=
|
||||
target_rs->get_attrib(MaterialAttrib::get_class_slot())) {
|
||||
altered |= Shader::SSD_material;
|
||||
}
|
||||
if (_state_rs->get_attrib(ShaderAttrib::get_class_slot()) !=
|
||||
target_rs->get_attrib(ShaderAttrib::get_class_slot())) {
|
||||
altered |= Shader::SSD_shaderinputs;
|
||||
}
|
||||
if (_state_rs->get_attrib(FogAttrib::get_class_slot()) !=
|
||||
target_rs->get_attrib(FogAttrib::get_class_slot())) {
|
||||
altered |= Shader::SSD_fog;
|
||||
}
|
||||
if (_state_rs->get_attrib(LightAttrib::get_class_slot()) !=
|
||||
target_rs->get_attrib(LightAttrib::get_class_slot())) {
|
||||
altered |= Shader::SSD_light;
|
||||
}
|
||||
if (_state_rs->get_attrib(ClipPlaneAttrib::get_class_slot()) !=
|
||||
target_rs->get_attrib(ClipPlaneAttrib::get_class_slot())) {
|
||||
altered |= Shader::SSD_clip_planes;
|
||||
}
|
||||
if (_state_rs->get_attrib(TexMatrixAttrib::get_class_slot()) !=
|
||||
target_rs->get_attrib(TexMatrixAttrib::get_class_slot())) {
|
||||
altered |= Shader::SSD_tex_matrix;
|
||||
}
|
||||
}
|
||||
_state_rs = target_rs;
|
||||
}
|
||||
|
||||
// Is this the first time this shader is used this frame?
|
||||
int frame_number = ClockObject::get_global_clock()->get_frame_count();
|
||||
if (frame_number != _frame_number) {
|
||||
altered |= Shader::SSD_frame;
|
||||
_frame_number = frame_number;
|
||||
}
|
||||
|
||||
if (altered != 0) {
|
||||
issue_parameters(altered);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLShaderContext::issue_parameters
|
||||
// Access: Public
|
||||
@ -1545,35 +1647,30 @@ unbind() {
|
||||
// or TransformState has changed, but the Shader
|
||||
// itself has not changed. It loads new values into the
|
||||
// shader's parameters.
|
||||
//
|
||||
// If "altered" is false, that means you promise that
|
||||
// the parameters for this shader context have already
|
||||
// been issued once, and that since the last time the
|
||||
// parameters were issued, no part of the render
|
||||
// state has changed except the external and internal
|
||||
// transforms.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(ShaderContext)::
|
||||
issue_parameters(int altered) {
|
||||
//PStatGPUTimer timer(_glgsg, _glgsg->_draw_set_state_shader_parameters_pcollector);
|
||||
PStatGPUTimer timer(_glgsg, _glgsg->_draw_set_state_shader_parameters_pcollector);
|
||||
|
||||
if (!valid()) {
|
||||
return;
|
||||
if (GLCAT.is_spam()) {
|
||||
GLCAT.spam()
|
||||
<< "Setting uniforms for " << _shader->get_filename()
|
||||
<< " (altered 0x" << hex << altered << dec << ")\n";
|
||||
}
|
||||
|
||||
if (_frame_number_loc != -1) {
|
||||
int current_frame = ClockObject::get_global_clock()->get_frame_count();
|
||||
if (current_frame != _frame_number) {
|
||||
_glgsg->_glUniform1i(_frame_number_loc, current_frame);
|
||||
_frame_number = current_frame;
|
||||
// We have no way to track modifications to PTAs, so we assume that
|
||||
// they are modified every frame and when we switch ShaderAttribs.
|
||||
if (altered & (Shader::SSD_shaderinputs | Shader::SSD_frame)) {
|
||||
|
||||
// If we have an osg_FrameNumber input, set it now.
|
||||
if ((altered | Shader::SSD_frame) != 0 && _frame_number_loc >= 0) {
|
||||
_glgsg->_glUniform1i(_frame_number_loc, _frame_number);
|
||||
}
|
||||
}
|
||||
|
||||
// Iterate through _ptr parameters
|
||||
for (int i = 0; i < (int)_shader->_ptr_spec.size(); ++i) {
|
||||
Shader::ShaderPtrSpec &spec = _shader->_ptr_spec[i];
|
||||
// Iterate through _ptr parameters
|
||||
for (int i = 0; i < (int)_shader->_ptr_spec.size(); ++i) {
|
||||
Shader::ShaderPtrSpec &spec = _shader->_ptr_spec[i];
|
||||
|
||||
if (altered & (spec._dep[0] | spec._dep[1])) {
|
||||
const Shader::ShaderPtrData* ptr_data = _glgsg->fetch_ptr_parameter(spec);
|
||||
if (ptr_data == NULL) { //the input is not contained in ShaderPtrData
|
||||
release_resources();
|
||||
@ -1657,10 +1754,14 @@ issue_parameters(int altered) {
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < (int)_shader->_mat_spec.size(); ++i) {
|
||||
Shader::ShaderMatSpec &spec = _shader->_mat_spec[i];
|
||||
if (altered & _shader->_mat_deps) {
|
||||
for (int i = 0; i < (int)_shader->_mat_spec.size(); ++i) {
|
||||
Shader::ShaderMatSpec &spec = _shader->_mat_spec[i];
|
||||
|
||||
if ((altered & (spec._dep[0] | spec._dep[1])) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (altered & (spec._dep[0] | spec._dep[1])) {
|
||||
const LMatrix4 *val = _glgsg->fetch_specified_value(spec, altered);
|
||||
if (!val) continue;
|
||||
#ifndef STDFLOAT_DOUBLE
|
||||
@ -1814,12 +1915,12 @@ update_shader_vertex_arrays(ShaderContext *prev, bool force) {
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef SUPPORT_IMMEDIATE_MODE
|
||||
if (_glgsg->_use_sender) {
|
||||
GLCAT.error() << "immediate mode shaders not implemented yet\n";
|
||||
} else
|
||||
#endif // SUPPORT_IMMEDIATE_MODE
|
||||
{
|
||||
if (valid()) {
|
||||
// Get the active ColorAttrib. We'll need it to determine how to
|
||||
// apply vertex colors.
|
||||
const ColorAttrib *color_attrib;
|
||||
_state_rs->get_attrib_def(color_attrib);
|
||||
|
||||
const GeomVertexArrayDataHandle *array_reader;
|
||||
Geom::NumericType numeric_type;
|
||||
int start, stride, num_values;
|
||||
@ -1845,7 +1946,7 @@ update_shader_vertex_arrays(ShaderContext *prev, bool force) {
|
||||
// Don't apply vertex colors if they are disabled with a ColorAttrib.
|
||||
int num_elements, element_stride, divisor;
|
||||
bool normalized;
|
||||
if ((p != _color_attrib_index || _glgsg->_vertex_colors_enabled) &&
|
||||
if ((p != _color_attrib_index || color_attrib->get_type() == ColorAttrib::T_vertex) &&
|
||||
_glgsg->_data_reader->get_array_info(name, array_reader,
|
||||
num_values, numeric_type,
|
||||
normalized, start, stride, divisor,
|
||||
@ -1891,9 +1992,9 @@ update_shader_vertex_arrays(ShaderContext *prev, bool force) {
|
||||
if (p == _color_attrib_index) {
|
||||
// Vertex colors are disabled or not present. Apply flat color.
|
||||
#if defined(STDFLOAT_DOUBLE) && !defined(OPENGLES)
|
||||
_glgsg->_glVertexAttrib4dv(p, _glgsg->_scene_graph_color.get_data());
|
||||
_glgsg->_glVertexAttrib4dv(p, color_attrib->get_color().get_data());
|
||||
#else
|
||||
_glgsg->_glVertexAttrib4fv(p, _glgsg->_scene_graph_color.get_data());
|
||||
_glgsg->_glVertexAttrib4fv(p, color_attrib->get_color().get_data());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -1926,6 +2027,8 @@ disable_shader_texture_bindings() {
|
||||
return;
|
||||
}
|
||||
|
||||
DO_PSTATS_STUFF(_glgsg->_texture_state_pcollector.add_level(1));
|
||||
|
||||
for (int i = 0; i < _shader->_tex_spec.size(); ++i) {
|
||||
#ifndef OPENGLES
|
||||
// Check if bindless was used, if so, there's nothing to unbind.
|
||||
@ -1960,9 +2063,7 @@ disable_shader_texture_bindings() {
|
||||
break;
|
||||
|
||||
case Texture::TT_3d_texture:
|
||||
#ifndef OPENGLES_1
|
||||
glBindTexture(GL_TEXTURE_3D, 0);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case Texture::TT_2d_texture_array:
|
||||
@ -2026,9 +2127,9 @@ disable_shader_texture_bindings() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(ShaderContext)::
|
||||
update_shader_texture_bindings(ShaderContext *prev) {
|
||||
if (prev) {
|
||||
prev->disable_shader_texture_bindings();
|
||||
}
|
||||
//if (prev) {
|
||||
// prev->disable_shader_texture_bindings();
|
||||
//}
|
||||
|
||||
if (!valid()) {
|
||||
return;
|
||||
@ -2134,8 +2235,10 @@ update_shader_texture_bindings(ShaderContext *prev) {
|
||||
|
||||
// We get the TextureAttrib directly from the _target_rs, not the
|
||||
// filtered TextureAttrib in _target_texture.
|
||||
const TextureAttrib *texattrib = DCAST(TextureAttrib, _glgsg->_target_rs->get_attrib_def(TextureAttrib::get_class_slot()));
|
||||
nassertv(texattrib != (TextureAttrib *)NULL);
|
||||
const TextureAttrib *texattrib;
|
||||
_glgsg->_target_rs->get_attrib_def(texattrib);
|
||||
//const TextureAttrib *texattrib;
|
||||
//_state_rs->get_attrib_def(TextureAttrib::get_class_slot());
|
||||
|
||||
for (int i = 0; i < (int)_shader->_tex_spec.size(); ++i) {
|
||||
Shader::ShaderTexSpec &spec = _shader->_tex_spec[i];
|
||||
|
@ -45,19 +45,23 @@ public:
|
||||
bool get_sampler_texture_type(int &out, GLenum param_type);
|
||||
|
||||
INLINE bool valid(void);
|
||||
void bind(bool reissue_parameters = true);
|
||||
void bind();
|
||||
void unbind();
|
||||
|
||||
void set_state_and_transform(const RenderState *state,
|
||||
const TransformState *modelview_transform,
|
||||
const TransformState *projection_transform);
|
||||
|
||||
void issue_parameters(int altered);
|
||||
void update_transform_table(const TransformTable *table);
|
||||
void update_slider_table(const SliderTable *table);
|
||||
void disable_shader_vertex_arrays();
|
||||
bool update_shader_vertex_arrays(ShaderContext *prev, bool force);
|
||||
void disable_shader_texture_bindings();
|
||||
void update_shader_texture_bindings(ShaderContext *prev);
|
||||
void disable_shader_texture_bindings() OVERRIDE;
|
||||
void update_shader_texture_bindings(ShaderContext *prev) OVERRIDE;
|
||||
|
||||
INLINE bool uses_standard_vertex_arrays(void);
|
||||
INLINE bool uses_custom_vertex_arrays(void);
|
||||
INLINE bool uses_custom_texture_bindings(void);
|
||||
|
||||
private:
|
||||
bool _validated;
|
||||
@ -65,6 +69,10 @@ private:
|
||||
typedef pvector<GLuint> GLSLShaders;
|
||||
GLSLShaders _glsl_shaders;
|
||||
|
||||
CPT(RenderState) _state_rs;
|
||||
CPT(TransformState) _modelview_transform;
|
||||
CPT(TransformState) _projection_transform;
|
||||
|
||||
//struct ParamContext {
|
||||
// CPT(InternalName) _name;
|
||||
// GLint _location;
|
||||
|
@ -416,7 +416,17 @@ cp_dependency(ShaderMatInput inp) {
|
||||
if ((inp == SMO_model_to_view) ||
|
||||
(inp == SMO_view_to_model) ||
|
||||
(inp == SMO_model_to_apiview) ||
|
||||
(inp == SMO_apiview_to_model)) {
|
||||
(inp == SMO_apiview_to_model) ||
|
||||
(inp == SMO_view_to_world) ||
|
||||
(inp == SMO_world_to_view) ||
|
||||
(inp == SMO_view_x_to_view) ||
|
||||
(inp == SMO_view_to_view_x) ||
|
||||
(inp == SMO_apiview_x_to_view) ||
|
||||
(inp == SMO_view_to_apiview_x) ||
|
||||
(inp == SMO_clip_x_to_view) ||
|
||||
(inp == SMO_view_to_clip_x) ||
|
||||
(inp == SMO_apiclip_x_to_view) ||
|
||||
(inp == SMO_view_to_apiclip_x)) {
|
||||
dep |= SSD_transform;
|
||||
}
|
||||
if ((inp == SMO_texpad_x) ||
|
||||
@ -438,6 +448,25 @@ cp_dependency(ShaderMatInput inp) {
|
||||
(inp == SMO_apiclip_x_to_view) ||
|
||||
(inp == SMO_view_to_apiclip_x)) {
|
||||
dep |= SSD_shaderinputs;
|
||||
|
||||
if ((inp == SMO_alight_x) ||
|
||||
(inp == SMO_dlight_x) ||
|
||||
(inp == SMO_plight_x) ||
|
||||
(inp == SMO_slight_x) ||
|
||||
(inp == SMO_satten_x) ||
|
||||
(inp == SMO_vec_constant_x_attrib) ||
|
||||
(inp == SMO_view_x_to_view) ||
|
||||
(inp == SMO_view_to_view_x) ||
|
||||
(inp == SMO_apiview_x_to_view) ||
|
||||
(inp == SMO_view_to_apiview_x) ||
|
||||
(inp == SMO_clip_x_to_view) ||
|
||||
(inp == SMO_view_to_clip_x) ||
|
||||
(inp == SMO_apiclip_x_to_view) ||
|
||||
(inp == SMO_view_to_apiclip_x)) {
|
||||
// We can't track changes to these yet, so we have to assume that
|
||||
// they are modified every frame.
|
||||
dep |= SSD_frame;
|
||||
}
|
||||
}
|
||||
if ((inp == SMO_light_ambient) ||
|
||||
(inp == SMO_light_source_i_attrib)) {
|
||||
@ -455,6 +484,21 @@ cp_dependency(ShaderMatInput inp) {
|
||||
if (inp == SMO_texmat_i || inp == SMO_inv_texmat_i) {
|
||||
dep |= SSD_tex_matrix;
|
||||
}
|
||||
if ((inp == SMO_window_size) ||
|
||||
(inp == SMO_pixel_size) ||
|
||||
(inp == SMO_frame_number) ||
|
||||
(inp == SMO_frame_time) ||
|
||||
(inp == SMO_frame_delta)) {
|
||||
dep |= SSD_frame;
|
||||
}
|
||||
if ((inp == SMO_clip_to_view) ||
|
||||
(inp == SMO_view_to_clip) ||
|
||||
(inp == SMO_apiclip_to_view) ||
|
||||
(inp == SMO_view_to_apiclip) ||
|
||||
(inp == SMO_apiview_to_apiclip) ||
|
||||
(inp == SMO_apiclip_to_apiview)) {
|
||||
dep |= SSD_projection;
|
||||
}
|
||||
|
||||
return dep;
|
||||
}
|
||||
@ -857,6 +901,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
|
||||
}
|
||||
cp_optimize_mat_spec(bind);
|
||||
_mat_spec.push_back(bind);
|
||||
_mat_deps |= bind._dep[0] | bind._dep[1];
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -931,6 +976,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
|
||||
|
||||
cp_optimize_mat_spec(bind);
|
||||
_mat_spec.push_back(bind);
|
||||
_mat_deps |= bind._dep[0] | bind._dep[1];
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -944,6 +990,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
|
||||
|
||||
cp_optimize_mat_spec(bind);
|
||||
_mat_spec.push_back(bind);
|
||||
_mat_deps |= bind._dep[0] | bind._dep[1];
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -967,6 +1014,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
|
||||
|
||||
cp_optimize_mat_spec(bind);
|
||||
_mat_spec.push_back(bind);
|
||||
_mat_deps |= bind._dep[0] | bind._dep[1];
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -988,6 +1036,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
|
||||
|
||||
cp_optimize_mat_spec(bind);
|
||||
_mat_spec.push_back(bind);
|
||||
_mat_deps |= bind._dep[0] | bind._dep[1];
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1029,6 +1078,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
|
||||
}
|
||||
cp_optimize_mat_spec(bind);
|
||||
_mat_spec.push_back(bind);
|
||||
_mat_deps |= bind._dep[0] | bind._dep[1];
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1051,6 +1101,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
|
||||
|
||||
cp_optimize_mat_spec(bind);
|
||||
_mat_spec.push_back(bind);
|
||||
_mat_deps |= bind._dep[0] | bind._dep[1];
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1072,6 +1123,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
|
||||
|
||||
cp_optimize_mat_spec(bind);
|
||||
_mat_spec.push_back(bind);
|
||||
_mat_deps |= bind._dep[0] | bind._dep[1];
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1093,6 +1145,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
|
||||
|
||||
cp_optimize_mat_spec(bind);
|
||||
_mat_spec.push_back(bind);
|
||||
_mat_deps |= bind._dep[0] | bind._dep[1];
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1139,6 +1192,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
|
||||
|
||||
cp_optimize_mat_spec(bind);
|
||||
_mat_spec.push_back(bind);
|
||||
_mat_deps |= bind._dep[0] | bind._dep[1];
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1195,6 +1249,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
|
||||
bind._arg[1] = NULL;
|
||||
cp_optimize_mat_spec(bind);
|
||||
_mat_spec.push_back(bind);
|
||||
_mat_deps |= bind._dep[0] | bind._dep[1];
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1215,6 +1270,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
|
||||
bind._arg[1] = NULL;
|
||||
cp_optimize_mat_spec(bind);
|
||||
_mat_spec.push_back(bind);
|
||||
_mat_deps |= bind._dep[0] | bind._dep[1];
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1261,8 +1317,12 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
|
||||
bind._id = p._id;
|
||||
bind._arg = kinputname;
|
||||
bind._info = p;
|
||||
bind._dep[0] = SSD_general | SSD_shaderinputs;
|
||||
bind._dep[1] = SSD_general | SSD_NONE;
|
||||
|
||||
// We specify SSD_frame because a PTA may be modified by the app
|
||||
// from frame to frame, and we have no way to know. So, we must
|
||||
// respecify a PTA at least once every frame.
|
||||
bind._dep[0] = SSD_general | SSD_shaderinputs | SSD_frame;
|
||||
bind._dep[1] = SSD_NONE;
|
||||
|
||||
memcpy(bind._dim,arg_dim,sizeof(int)*3);
|
||||
|
||||
@ -2050,7 +2110,8 @@ Shader(ShaderLanguage lang) :
|
||||
_parse(0),
|
||||
_loaded(false),
|
||||
_language(lang),
|
||||
_last_modified(0)
|
||||
_last_modified(0),
|
||||
_mat_deps(0)
|
||||
{
|
||||
#ifdef HAVE_CG
|
||||
_cg_vprogram = 0;
|
||||
|
@ -273,6 +273,8 @@ public:
|
||||
SSD_light = 0x080,
|
||||
SSD_clip_planes = 0x100,
|
||||
SSD_tex_matrix = 0x200,
|
||||
SSD_frame = 0x400,
|
||||
SSD_projection = 0x800,
|
||||
};
|
||||
|
||||
enum ShaderBug {
|
||||
@ -529,6 +531,7 @@ public:
|
||||
epvector <ShaderMatSpec> _mat_spec;
|
||||
pvector <ShaderTexSpec> _tex_spec;
|
||||
pvector <ShaderVarSpec> _var_spec;
|
||||
int _mat_deps;
|
||||
|
||||
bool _error_flag;
|
||||
ShaderFile _text;
|
||||
|
@ -36,8 +36,10 @@ class EXPCL_PANDA_GOBJ ShaderContext: public SavedContext {
|
||||
public:
|
||||
INLINE ShaderContext(Shader *se);
|
||||
|
||||
INLINE virtual void set_state_and_transform(const RenderState *, const TransformState *, const TransformState*) {};
|
||||
|
||||
INLINE virtual bool valid() { return false; }
|
||||
INLINE virtual void bind(bool reissue_parameters = true) {};
|
||||
INLINE virtual void bind() {};
|
||||
INLINE virtual void unbind() {};
|
||||
INLINE virtual void issue_parameters(int altered) {};
|
||||
INLINE virtual void disable_shader_vertex_arrays() {};
|
||||
@ -47,7 +49,6 @@ public:
|
||||
|
||||
INLINE virtual bool uses_standard_vertex_arrays(void) { return true; };
|
||||
INLINE virtual bool uses_custom_vertex_arrays(void) { return false; };
|
||||
INLINE virtual bool uses_custom_texture_bindings(void) { return false; };
|
||||
|
||||
PUBLISHED:
|
||||
INLINE Shader *get_shader() const;
|
||||
|
@ -141,10 +141,9 @@ private:
|
||||
static int _attrib_slot;
|
||||
};
|
||||
|
||||
ostream &operator << (ostream &out, ColorBlendAttrib::Mode mode);
|
||||
ostream &operator << (ostream &out, ColorBlendAttrib::Operand operand);
|
||||
EXPCL_PANDA_PGRAPH ostream &operator << (ostream &out, ColorBlendAttrib::Mode mode);
|
||||
EXPCL_PANDA_PGRAPH ostream &operator << (ostream &out, ColorBlendAttrib::Operand operand);
|
||||
|
||||
#include "colorBlendAttrib.I"
|
||||
|
||||
#endif
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user