I actually have been working on replacing the parts of the renderer that use already deprecated OpenGL functionality (including the whole fixed GL pipeline) with modern functionality, so I have learned a bit about the renderer. I have worked on the tremulous code, but I guess the same code would work on ioq3 too, the Tremulous svn usually only imports from ioquake in the renderer subdirectory.
My modified renderer translates the Quake 3 shaders into GLSL programs and uploads all the map geometry into VBOs. So the renderer just needs to find the potentially visible surfaces, bind the right programs and VBOs and issue the draw call. However, the FPS stayed on the same order of magnitude as the default renderer. So here are my thoughts about the subject: The big issue to supporting a modern renderer is of course keeping compatibility to the existing data. But there are differences: If you want to support skeletal animations you not only have to support another file format in the renderer, but the animations have to be controlled differently. The current qvm just tells the renderer "hey, draw this model interpolated 87% between frame 5 and 6", i.e. the renderer has no idea about the animation.cfg, everything is controlled by the qvm. To control a skeletal animation you have to pass a list of bone positions or similar. This means you need a new interface for skeletal animation and consequently new qvms. If you just want to support new shader effects like parallax mapping, this could be done without the qvm even knowing about it. You could put the required normal maps into the pk3s, and if you extend the shaders scripts in a way the old clients ignore the new instructions, this could be implemented fully backward compatible, i.e. new clients can play old maps, old clients can play new maps. A more advanced lighting model would be possible without qvm/map changes, but unfortunately the current bsp discards all information about static light sources and keeps only the generated light maps and the light grid. For effects like specular lighting you need the light direction, but you only know the light intensity. The original renderer's specular alpha cheats here and simply defines a fixed light position that is used for all specular calculations, and no, this is not the location of the sun, but a point hardcoded in tr_shade_calc.c.... If you want to go for higher performance, there is obviously no need to break compatibility, but as I said before, the FPS gained by offloading calculations to the GPU is not astronomical. Why is this so ? Well firstly most levels are designed for the current renderer, which means the bulk of the maps doesn't use any fance shader scripts at all. Rendering single-pass texture*lightmap surfaces is not a big issue on CPU or GPU. If you add shader effects to every surface, a GLSL renderer would have less problems to handle it, but current maps simply don't do it because they target the original renderer. Secondly modern GPUs can render insane amounts of vertexes because they are very parallel architectures. But this works only when you have many vertexes and/or fragments that are processed identically. If you have >1000 shader units on your GPU and tell them to render a single 4-vertex quad, it just doesn't scale. Ideally you give the GPU a few large batches of data that each have to be processed identically, but the Q3 maps usually have lots of surfaces each with it's own shader/texture, so that you can only push a few vertexes until you have to change the GL state again. (If you actually try to render a batch of more than 1000 vertexes, the renderer will even split it up !) So, IMHO, there are some points that have to be decided: - pluggable renderer or not: putting the renderer in a DLL/so should be possible with medium effort, the engine calls into the renderer only via the refexport_t, but the renderer doesn't always use the corresponding refimport_t. - update the old renderer or create a new one: without renderer plugins the question is moot, but if there is a plugin structure should the original renderer be kept as is ? - what is the target of the new renderer ? The current renderer targets OpenGL 1.1, with some extensions. A new renderer could target 2.1 (~DirectX9), 3.4 (~DirectX10) or 4.0 (~DirectX11). Other possible targets would be DirectX9/10/11 or OpenGL ES 2.0. - how do you want to handle features that require new data ? should it be possible to run a new map on an old client (without the new features ofc), or is it ok if old clients fail on a new map ? - do you want to preserve qvm/shader/bsp compatibility ? some features will require new qvms, others only new shaders or a new bsp format.
_______________________________________________ ioquake3 mailing list [email protected] http://lists.ioquake.org/listinfo.cgi/ioquake3-ioquake.org By sending this message I agree to love ioquake3 and libsdl.
