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.

Reply via email to