|
From: Dair G. <da...@re...> - 2004-06-01 20:36:45
|
James W. Walker wrote:
>I'd like to add an option to Quesa to leave the depth buffer=20
>uncleared when rendering.
Good idea.
>I'm wondering what sort of API to use. One option would be to add a
>flag to the TQ3DrawContextClearImageMethod enumeration. However, the
>option may not make sense for non-OpenGL renderers. Another option
>would be to do it like the depth buffer depth, with a custom element
>attached to the renderer, view, or draw context.
Hmm, yeah, the depth buffer depth thing is something I've been wondering
about as well - we could keep extending everything through new elements
(depth value to clear to, stencil value to clear through, etc), or
perhaps we should start thinking about extending the API/structures we
use?
One of the things QD3D did try and do was come up with one interface
that would work everywhere, even if the effects were optional (e.g., the
cast/receive shadows styles would have no effect in the interactive
renderer but would in others), so using custom elements for everything
might be pushing it too far.
Proposal 1
----------
Extend the TQ3DrawContextClearImageMethod enum to be a bitfield rather
than an enum:
typedef enum {
kQ3ClearMethodNone =3D 0,
kQ3ClearMethodMaskColor =3D (1 << 2),
kQ3ClearMethodMaskDepth =3D (1 << 3),
kQ3ClearMethodMaskStencil =3D (1 << 4),
kQ3ClearMethodMaskAccumulation =3D (1 << 5),
kQ3ClearMethodClearAll =3D 1,
kQ3ClearMethodWithColor =3D kQ3ClearMethodDefault,
kQ3ClearMethodSize32 =3D 0xFFFFFFFF
} TQ3DrawContextClearImageMethod;
kQ3ClearMethodNone is at present: nothing is cleared.
The kQ3ClearMethodMaskXXX methods can be or'd together, to indicate the
specific buffers to be cleared. This gives us plenty of room to add more
buffer types later.
The kQ3ClearMethodClearAll method implies that every buffer will be
cleared: it's equvialent to what 0xFFFFFFFF would be for a bitfield.
The kQ3ClearMethodWithColor value needs to be retained for backwards
compatibility, so maps to kQ3ClearMethodClearAll as that's the behaviour
of the old enum (it says WithColor, but it clears the depth buffer too).
The drawbacks here are:
- kQ3ClearMethodClearAll has to have the value 1 rather than 0xFFFFFFFF
so it's not quite as obvious as it should be.
- There's no way to specify the value the depth, stencil, accumulation,
or future (1<<6, etc) buffers should be cleared to
Proposal 2
----------
Replace the draw context API with one that's future-proof, but not 100%
backwards compatible.
This means you won't be able to take a QD3D app and use it as-is, but is
that still going to be a problem? After N years of saying we must be
backwards compatible, I realise this must sound a bit shocking. :-)
Aside from the obvious downside, the plus points would be:
- TQ3DrawContextClearImageMethod could be a bitfield with masks and a
ClearAll that corresponded to 0xFFFFFFFF
- TQ3MacDrawContext2DLibrary would be removed, as QuickDraw GX is a
no-op.
- TQ3DrawContextData would contain additional fields for the various
ways it could be cleared. Not sure what the best approach is: perhaps
something as simple as a 32-element array of unions that could hold
everything? Or a void* to an array of these unions that gets held
externally?
- TQ3MacDrawContextData would lose the viewPort and grafPort fields.
The question is, how much upgrading of client code is acceptible in
order to let the API grow? If it was done in such a way that existing
code continued to work, but new features mean using a new API, would
that be OK?
Don't know - just thinking out loud. One of the problems with the
original API is there's no way to extend these structures in the future
without breaking older code.
If each structure started with a size or version field then this problem
would be avoided, so perhaps this would be a good point to think about
gradually upgrading the API to be future-proof?
The alternative is that we build up a big list of custom elements for
all our additional state, but I can see that getting more and more
unwieldy over time (some state's held in a struct, some is attached to
an object, you don't really know which is where).
I guess an ideal-looking API for me would be:
- Version/size-tagged struct to create objects and do batch data get/set
- A common Q3Object_GetValue/SetValue API to assign tagged values to an
object
The two Apple APIs that I've seen work really well have been
CarbonEvents.h and ControlDefinitions.h. Once you have a system in place
to get/set arbitary-sized values by name then extending the API becomes
a lot easier.
Any thoughts?
-dair
___________________________________________________
mailto:dair+refnum.com http://www.refnum.com/
|