gl shader anomalies

First I get following error quite randomly

Traceback (most recent call last):
  File "c:\panda_cvs\debug\direct\showbase\ShowBase.py", line 1697, in __igLoop
    self.graphicsEngine.renderFrame()
AssertionError: Shader input pos is not present.

So I tracked it down little bit.
the call stack contains this

libpandagl_d.dll!GLGraphicsStateGuardian::set_state_and_transform(const RenderState * target=0x0efcf270, const TransformState * transform=0x106265c0) Line 7007

#ifndef OPENGLES_1
    if (_current_shader_context) {
      _current_shader_context->issue_parameters(this, Shader::SSD_color);
->      _current_shader_context->issue_parameters(this, Shader::SSD_colorscale);
    }
#endif

and ends with error mentioned above

next fragment:

libpandagl_d.dll!GLShaderContext::issue_parameters(GLGraphicsStateGuardian * gsg=0x0036a2d4, int altered=4) Line 627 + 0x25 bytes

  //FIXME: this could be much faster if we used deferred parameter setting.

  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 LMatrix4f *val = gsg->fetch_specified_value(_shader->_mat_spec[i], altered);

-> is the next is next statment to be executed.

It does make much sense why issuing Shader::SSD_color will require reading custom shader input.

here is complete call stack
pastebin.com/B3GxML7U

I agree, it doesn’t make much sense. Where is the line that actually generates the assertion in question? Are you sure you’re looking at the right call stack? (Note that you can set “assert-abort 1” to generate a C++ except at the time of the assertion, which makes it much easier to see the actual stack.)

Also note that, due to the way OpenGL exceptions are raised (they have to be explicitly queried by report_my_gl_errors()), you will only see OpenGL exceptions reported at certain checkpoints, so it’s possible to get an exception reported sometime later than the actual exception occurred, if someone missed an appropriate checkpoint spot.

David

I added breakpoint to the assertion line, so the call stack is correct.

Anyhow I now added this “assert-abort 1”
and here is almost the same stack
pastebin.com/8jLi5Ack

Seems that in code below spec._dep[0] is uninitialized somehow and if statement fails.
That would explain that randomness I’m seeing.

const LMatrix4f *GraphicsStateGuardian::
fetch_specified_value(Shader::ShaderMatSpec &spec, int altered) {
  LVecBase3f v;
  
  if (altered & spec._dep[0]) {
    if (t != &spec._cache[0]) {
      spec._cache[0] = *t;
    }
  }
...

Screenshot with data:

Will dig deeper.

initializing the _dep in GLShaderContext::Constructor seems fix the issue

...
            case GL_FLOAT_VEC4: {
              Shader::ShaderMatSpec bind;
              bind._id = arg_id;
              switch (param_type) {
              case GL_BOOL:
              case GL_FLOAT:      bind._piece = Shader::SMP_row3x1; break;
              case GL_BOOL_VEC2:
              case GL_FLOAT_VEC2: bind._piece = Shader::SMP_row3x2; break;
              case GL_BOOL_VEC3:
              case GL_FLOAT_VEC3: bind._piece = Shader::SMP_row3x3; break;
              case GL_BOOL_VEC4:
              case GL_FLOAT_VEC4: bind._piece = Shader::SMP_row3  ; break;
             }
*             bind._dep[0]  = Shader::SSD_general | Shader::SSD_shaderinputs;
*             bind._dep[1]  = Shader::SSD_general | Shader::SSD_NONE;
              bind._func = Shader::SMF_first;
              bind._part[0] = Shader::SMO_vec_constant_x;
              bind._arg[0] = inputname;
              bind._part[1] = Shader::SMO_identity;
              bind._arg[1] = NULL;
              s->_mat_spec.push_back(bind);
...

I’m not sure if I initialized it correctly, but the error is gone along with other anomalies.

So I guess, the same should do with cvs code. Also there are other places where this member is uninitialized.

Ah, excellent detective work, thank you! Would you mind taking a look at all of the uninitialized pathways and committing the appropriate change? Thanks!

David

Awesome, thanks very much for your investigation! I’ve been running into this same issue a few days ago, and wasn’t able to find a solution.

I’m working on updating a project that dates back to 2006, and is still running in production on panda 1.4.2. I downloaded the latest stable release and 1.8 for Natty Narwhal, then began experiencing this problem in both recent versions.

I have downloaded the latest tarball from sourceforge, and it looks to me like the change that andresv identified was never committed. David, you indicated that there were more places where these shader inputs would be passed through, and where this change would need to be made?

I will spend the rest of the evening trying to build from the source and see if I can confirm this fix in my situation, but it’s been five years since I’ve built from source, and I’ve never spent any meaningful time in the c++ source for panda3d, so I doubt it’s very wise for me to try to commit the patch.

What would you guys advise?
-pl-

(Bump - my problem remains)

I’m still working on this issue–I finished resolving all the missing libraries on my out-of-the-box ubuntu installation so that the source code for panda3d would compile. I ran

makepanda --everything --installer

and then installed the .deb that resulted. I had applied the change from above by hand, but my original problem remained:

AssertionError: Shader input colorid is not present.

Thanks for any help! I’ll keep working on the problem until I solve it one way or another.

-pl-

If anyone’s interested, here is some code which exhibits the problem. I was thinking of offering this as a sample to add to the library when I wrote it with Josh in 2007, but he said the technique was too weird to endorse in that way. So be it.

pastebin.com/57KvZKLB

Usually you get this message because a frame is being rendered before all the necessary inputs have been set on objects with shaders applied. I would guess it is happening on your call to renderFrame.
You could try setting a default for colorid by calling setShaderInput on render before renderFrame ever has a chance to be called.

bingo, in the source code i pasted above, the ‘sky’ node wasn’t being initialized with shader inputs–evidently that may have been OK in 2007, but isn’t anymore. or maybe the lines got lost somehow and i didn’t notice it when i returned to working on the project.

thank you so much! now i can get on with actually fixing things.

-pl-