batching style question

I’ve implemented a batcher for the fixed pipeline. The batcher will sort according to the states a batch requires and then, after setting relevant states, will call into a rendering function like the one below for the skybox. I also use VBO caching like Photon suggested.

My questions:

  • should I make the static const variables member variables for better perf or some other concern (no threads here, nor will there ever be),
  • maybe there should be no render functions at all? Here a batch is a block of states, without including the various vertex attribute pointers, as these almost always change from batch to batch. Also I didn’t want to issue too many batches in situations, where I render many identical batches (I can’t instance). In other words, I don’t include everything necessary for a glDraw* call in a batch, but maybe I should?

All the rendering code looks like the one below. Some pointers are set, the modelview matrix, … maybe some other states… and then glDrawElements() follows.


//////////////////////////////////////////////////////////////////////////////
void Skyboxb::render_skyboxa()
{
  static GLsizei const strideaa(get_packed_stride((*vaa_ptr)[0]));
  static GLsizei const offseta(get_packed_offset((*vaa_ptr)[0], 2));
  static GLsizei const counta((*vaa_ptr)[1].array_size /
    GVA_to_size(ArrayElementType((*vaa_ptr)[1].attribute_infos[0].type)));

  get_vbo_handler().load_resource_range(
    (*vaa_ptr)[0].vbo_index,
    (*vaa_ptr)[1].vbo_index + 1);

  glVertexPointer(
    (*vaa_ptr)[0].attribute_infos[0].size + 1,
    GVA_to_GL(ArrayElementType((*vaa_ptr)[0].attribute_infos[0].type)),
    strideaa,
    get_vbo_handler().get_vbo_ptr((*vaa_ptr)[0].vbo_index));

  glTexCoordPointer(
    (*vaa_ptr)[0].attribute_infos[2].size + 1,
    GVA_to_GL(ArrayElementType((*vaa_ptr)[0].attribute_infos[2].type)),
    strideaa,
    get_vbo_handler().get_vbo_ptr((*vaa_ptr)[0].vbo_index) + offseta);

  glLoadMatrixf(model_matrix.data());

  glDrawElements(
    GL_TRIANGLES,
    counta,
    GVA_to_GL(ArrayElementType((*vaa_ptr)[1].attribute_infos[0].type)),
    get_vbo_handler().get_vbo_ptr((*vaa_ptr)[1].vbo_index));

  GL_DEBUG();
}

I just figured it out, static const variables are not that much of a problem with multithreading as the usual static variables. gcc outputs thread-safe code for handling the case of 2 threads entering into the same code block with static const variables.

Lol, how long will it take till I finally get it? In the code above I’ve (ab)used boost::function, boost::bind to call into the batch renderer. Now I just make a struct with info all batch renderers can use. Still boost::bind is mighty fun and more beautiful. It allows you to do something like this:

boost::bind(f, arg1, arg2, arg3)

so your batch renderer does not need to access some struct to render, but gets all it needs from the boost::bind functor. This makes for more readable code, in my opinion, but I am afraid the call overhead might eat too much CPU.