HWRAPI is split between a HWR_ function set that handles BSP tree traversal, etc, and is used to mask the details of the hardware renderer behind an interface that looks similar to the software renderer.
The OpenGL implementation is the only one really supported because HWRAPI was never actually completed (see: FTextureInfo typedefed to GLMipmap_s).
There are a few bottlenecks that seriously hinder performance at the moment and, if they were fixed, would help pave the way to OpenGL as the default renderer.
The main issue with GL performance is that DrawPolygon gets called way too often. This is a massive CPU bottleneck and affects even modern GPUs (<50fps in ERZ2 on a GTX770!) The backend interface expects that DrawPolygon immediately draws the given vertices. We should not change the interface behavior since it's actually fairly clear and we can fix this at the frontend level for a performance boost in both the current GL renderer and the future GLES (Android) renderer.
The main thing here is that, during BSP traversal, we should try to preclude a call to DrawPolygon with a preparation mechanism. Basically, we need to take all the triangles that we'd normally send to DrawPolygon, and put them into buckets based on which texture is currently in use. As a final draw step, we take those buckets, and do DrawPolygon for each texture bucket. This will make the map drawing step only use as many calls to glDrawArrays or whatever underlying mechanism as there are textures currently visible. This is a far cry from the draw call for every single triangle we've been doing up to now.
We don't really have to worry about thing drawing since that makes up a very tiny number of draw calls in comparison to highly detailed maps like ERZ2.
Some changes have already been posted for this for performance improvements (arrays instead), but if we switch to using shaders, we can pull off software pallet effects in OpenGL. We can have a fallback fixed function backend based on the current one if the player doesn't have GL2 features on their graphics device (surprisingly, this is somewhat common still).
We should use GLEW to figure out what GL version and extensions are currently available.
We should switch to using framebuffers for any frame capture effects (endlevel screen, upscaling).
Sector light function
Take sector's light level and divide it by 8. Call this value "lightnum". For walls, add 1 if the wall is straight vertically, and subtract 1 if the wall is straight horizontally. Clip this value to [0, 31].
Take the "scale" of the graphic (160 / distance from the camera in units should = "scale"), multiply by 4. Call this value "pindex". (I think this is multipled by 2 for flats, but don't quote me on that.) Clip this value to [0, 47].
((31-lightnum)*2)-(160/((pindex+1)>>9)) clipped to [0, 31] should be the index of the colormap to use, 0 being the fullbright one. If the result is wrong, this is probably where I screwed up.