In any case, I ended up going around my own codebase and writing a direct OpenGL test snippet, which behaves identically to my wrapper code: stuff is written to the color buffer if depth testing is disabled or depth func is set to GL_ALWAYS. Otherwise nothing is written. The result is attached and so are the relevant code snippets.
As I mentioned above, I'm probably missing something really simple and stupid.
PS - culling is disabled!
PPS - sorry for the shoddily formatted code - I threw it together
static GLuint fboId = 0;
static GLuint rboId = 0;
static GLuint textureId = 0;
if(!fboId)
{
#define TEXTURE_HEIGHT 512
#define TEXTURE_WIDTH 512
// create a texture object
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);
//set up the FBO - CHECK_FBO_STATUS succeeds for all calls
CHECK_FBO_STATUS(glGenFramebuffers(1, &fboId));
glBindFramebuffer(GL_FRAMEBUFFER, fboId);
CHECK_GL_ERROR(glGenRenderbuffers(1, &rboId));
CHECK_GL_ERROR(glBindRenderbuffer(GL_RENDERBUFFER, rboId));
CHECK_GL_ERROR(glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, TEXTURE_WIDTH, TEXTURE_HEIGHT));
CHECK_GL_ERROR(glBindRenderbuffer(GL_RENDERBUFFER, 0));
// attach a texture to FBO depth attachement point
CHECK_FBO_STATUS(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0));
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboId);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
//render code
glBindFramebuffer(GL_FRAMEBUFFER, fboId);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
//do some additional setup here, like setting up the camera and such
glEnable(GL_DEPTH_TEST); //<- specifically enable depth testing...
glDepthFunc(GL_LEQUAL);//...set up depth comparison...
glDepthMask(true);//... and enable masking
//nothing fancy - enables a shader and draws the buffered geometry; this part works properly
shdTerrain->Enable(drv);
drv->DrawVertexArray(vaHandle, GD_TRIANGLES);
shdTerrain->Disable();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
And here's a screenshot when depth testing is disabled, proving that it's not a color attachment, shader or vertex buffer issue. As noted above, when depth testing is enabled, nothing is drawn.
[attachment=12136:fbo depth.png]