1

Trying to utilize directional shadow mapping on OpenGL. Need to generate a depth texture that isn't a renderbuffer (need to be able to read from it) it future passes. Keep getting GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT (as result of glCheckFramebufferStatus) when running on Android (don't get error when running on OSX).

Here's my code:

 //Shadow
  //gen tex
  gl_shadow_bogus_texture_active_n = 7;
  glActiveTexture(GL_TEXTURE0+gl_shadow_bogus_texture_active_n);
  glGenTextures(1, &gl_shadow_bogus_texture_buff_id);
  glBindTexture(GL_TEXTURE_2D, gl_shadow_bogus_texture_buff_id);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,tex_dim.x,tex_dim.y,0,GL_RGB,GL_UNSIGNED_BYTE,0);

  //gen depth
  gl_shadow_texture_active_n = 4;
  glActiveTexture(GL_TEXTURE0+gl_shadow_texture_active_n);
  glGenTextures(1, &gl_shadow_texture_buff_id);
  glBindTexture(GL_TEXTURE_2D, gl_shadow_texture_buff_id);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  glTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT16,1024,1024,0,GL_DEPTH_COMPONENT,GL_FLOAT,0);

  glGenFramebuffers(1, &gl_shadow_framebuffer_id); //gen fb
  glBindFramebuffer(GL_FRAMEBUFFER, gl_shadow_framebuffer_id); //bind fb
  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gl_shadow_bogus_texture_buff_id, 0); //attach tex
  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, gl_shadow_texture_buff_id, 0); //attach depth

note that the whole gl_shadow_bogus_texture_buff_id thing (the generation and binding of the color texture) is just an attempt to fill out the framebuffer, thus getting rid of the error. I don't actually care about the color data.

a further note is that the "color tex gen/bind" is not necessary on mac, and can be replaced with glDrawBuffer(GL_NONE) and glReadBuffer(GL_NONE). But I can't compile with those in for android...

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
Phildo
  • 986
  • 2
  • 20
  • 36
  • What's `gl_shadow_texture_active_n` for? Also, are you checking for other OpenGL errors? – Nicol Bolas Feb 01 '16 at 01:06
  • @NicolBolas - `gl_blah_texture_active_n` is a means of me keeping track of which glActiveTexture that texture is bound to. I have few enough textures where I'm currently using a one-to-one texture_id-to-active_texture_n kind of architecture. Greatly simplifies things (though it renders the "ActiveTexture" layer of indirection redundant...). And yes- I'm checking for other OpenGL errors. They are all passing, so I left them out of sample code for readability. – Phildo Feb 01 '16 at 18:19
  • "*I have few enough textures where I'm currently using a one-to-one texture_id-to-active_texture_n kind of architecture.*" That makes no sense at all. If you're creating a texture, it should only be bound for that purpose; once created, you *unbind* it. – Nicol Bolas Feb 01 '16 at 18:50
  • Maybe I'm using the wrong terminology regarding "binding". At the end of the day, I need to pass in the `uniform sampler2D blah_tex;` to my shader. The way I do this is by passing the `ActiveTexture` (a `GLuint`) into `glUniform1i`. So any texture I use *must be associated with an ActiveTexture*. Where in certain cases, one might set the "active textures" just before a draw call that uses them, then switch them out for the next draw call that needs diff textures, I just set each texture into an activeTexture once, and never shuffle them. Is there something wrong with this line of thinking? – Phildo Feb 01 '16 at 20:28
  • "*Where in certain cases, one might set the "active textures" just before a draw call that uses them,*" No, that's not "in certain cases"; that's standard behavior for *most* OpenGL applications. The reason being that your way, which keeps all textures bounds and has you changing uniforms, limits the number of textures you can have around to the number of available texture image units. Texture binding points are supposed to be ephemeral; you set them as needed, and unset them once they are no longer needed. Maybe that works for small examples, but not for any programs of significance. – Nicol Bolas Feb 01 '16 at 20:51
  • which exactly justified my "I have few enough textures ..." statement, and reinforced my expressed model describing this layer of indirection... Your comment of "That makes no sense at all" and general aggressive tone is unhelpful and, well, bizarre. What do you want from me? – Phildo Feb 01 '16 at 21:32
  • From you? I expect nothing. What I would like is for everyone reading your code to know that it is not an example of good programming practices for OpenGL. You may or may not agree with this assessment, but I don't want anyone to get the idea that using texture units as *storage* for texture objects is in common use or is a good idea. – Nicol Bolas Feb 01 '16 at 21:43

1 Answers1

1

You do not have a stencil attachment, which is likely why you've getting a GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT error. Although not explicitly stated in the spec, most drivers require a stencil attachment when a depth attachment is also present. However, depending on the implementation, you may run into problems, because using GL_DEPTH_COMPONENT16 with a stencil attachment may not be a supported combination (in fact, in my experience, it usually isn't). Each driver is only required to support at least one combination - unfortunately, there's no way to query exactly what the combination might be. You basically just have to guess and hope it succeeds.

The majority of Android implementations support the packed depth stencil format DEPTH24_STENCIL8_OES, and the extension implicitly supports the depth being a texture which can be sampled. You will likely have considerably more success using it (but success is not guarateed!).

MuertoExcobito
  • 9,741
  • 2
  • 37
  • 78
  • Ah. Right on. The solution for me was just using `GL_DEPTH_COMPONENT` rather than `GL_DEPTH_COMPONENT16` to let it pick whatever is available. I didn't need to create/attach a stencil buffer. Would you recommend that I do anyways for compatibility purposes? Or does the "just depth attachment" functioning here imply it probably will elsewhere? – Phildo Feb 01 '16 at 18:21