(I considered taking this off-list, but the discussion is still
relevant to GL. It's a bit long though, so apologies to those of you
who already have enough to read!)
Yes, I suppose I am dragging this out a bit, so I should also convey my
apologies to other's on this list. I haven't looked into OpenGL for 2D
games for years now (since OS 9 was the primary OS), so please forgive
my ignorance.
Yes, slightly, assuming relatively modest object counts (say, a dozen
layers, one thousand sprites.) You trade per-frame CPU sorting for the
depth buffer clear time and the per-pixel depth test comparison. These
are very optimized on recent GPUs though so it won't make a big
difference. You will however also save the VRAM used by the depth
component of the framebuffer, which might be nice if you're already
low on VRAM.
Well every bit of VRAM counts :-)
If you are intending to update textures often, then you should stick
to 32 or 16 bpp BGRA. If you really want to have 15 bit RGB and 8 bit
A, then you'll have to make one RGB texture and one A texture and use
a second texture unit to mask. Also, be warned that while this will
save you 8 bits per texel on the ATI cards, I'm pretty sure that the
nvidia cards don't support an A8 internal texture format-- they will
upconvert it to L8A8 behind your back, so you'll still be using 32
bits in VRAM. It's probably easiest to just use RGBA8 if you need 8
bits of alpha. RGB5A1 is fine if you don't care about the alpha, and
well worth the VRAM saving if you can stand some color quality loss.
(The ATI cards also support R3G3B2, if you really want to pack the
textures in, but it looks pretty bad and isn't supported on nvidia.)
You might also check out the DXTC compressed formats, many games use
these. They're only appropriate for prerendered artwork that isn't
being animated though.
Well it wasn't something that I was dead set on. I've just used 15-bit
images with 8-bit alphas (for the mask) in past, and then I would write
a blitter to use the 8-bit alpha for transparency. I suppose I can
upload a RGBA8 texture to the card and then some how have OpenGL to use
the 8-bit alpha for transparency so I get the same result?
Yes, the render-to-texture texture is treated as a wrap-around work
area (aka "toroidal scrolling region.") You draw into it wherever the
newly exposed area is, and then blit then whole thing as four quads
(or two, if you only need strict vertical or horizontal scrolling) to
the viewport.
It's exactly as useful. You keep a render-to-texture work texture for
each parallax layer, and in each of these you only update a small
portion every frame. But you composite them all stacked on top of each
other, updating the entire viewport, every frame. (Unless you have a
really good reason, you should throw away any old CPU-era notions you
have about tracking dirty rectangle updates in GL. Just update the
whole viewport, let the GPU do its thing.)
That makes sense, I just wasn't thinking about using the
render-to-texture texture for single image backgrounds (which is what
my background layers), but as you've pointed out it's probably the best
solution.
Well I've got no reason to deal with dirty rects any more - I didn't
like them in the past anyways :-)
Note that overall, this method will end up using more total texture
RAM than you'd need just drawing artwork layers directly into the
viewport. But it minimizes AGP paging in the case where you have tons
of artwork, by caching the currently visible layer portions into work
textures in VRAM. And it allows you to treat each layer as a single
texture, which eliminates filtering artifacts (that you would have,
drawing a layer as i.e. a mesh of quads each textured from disparate
portions of a texture altas) and enables various effects that might
otherwise be costly (reusing the same layer multiple times,
transforming a layer as a single object, etc.)
Also, I should probably clarify the difference between my using the
term "render-to-texture texture", and John's talk about updating
subtexture portions. In the simple case of 2D panning over huge
artwork, all you need to do is glTexSubImage2D the appropriate areas
(this is in fact what my simple TileScroller demo does.) But for more
interesting games, you might want to creatively reuse artwork elements
in your layers, so you really need a render-to-texture context per
layer. Then you can draw from the artwork however you like;
transforming, colorizing, etc the artwork pieces as you update the
exposed portion of the layer. I'm sure you can come up with some
interesting applications if you think about it.
Well at times I plan on manipulating the entire screen image such as
rotations, and scaling it...
And many tiles will be animated so I'll be forced to redraw some of
them almost every frame...
More on this below...
No, that actually won't work if you are using rectangle textures
(which are, btw, required for optimal texture uploads) because REPEAT
wrap mode isn't supported. If you simply want to fill the viewport
with large repeating art just draw four (or two, for strict H/V
scrolling) quads textured from the appropriate section of the artwork.
However, if you want rotation, or your viewport scale does not match
your texture scale (as may be the case when you need to support
multiple display resolutions) or you otherwise need fractional
texturing (for example scrolling by subpixel amounts) then you will
have to watch out for filtering artifacts at the quad seams. In the
render-to-texture approach I used in my Tilescroller demo, I handle
this by faking REPEAT mode; I make the layer texture slightly bigger
than it needs to be (2 texels wider, rounding up to the nearest 8
texels, and 2 texels taller) and copy any updated edge texels to the
opposite border. But you can also check Apple's OpenGL Image sample
code for how to handle it manually by overlapping the quad edges in
the right way.
So there went my first ideal for multiple scrolling layers. I suppose
that leaves me with one of two options, the render-to-texture option
you have given me or simply creating a few extra quads and leap
frogging them over one another (such as when the user scrolls right I
would "leap frog" the left quad to the right of the other) - not a very
pretty method so I leaning much more toward the render-to-texture
option.
So my requirements are like so...redraw some tiles & sprites every
frame, parallax scrolling, and per layer or entire screen effects -
scaling, rotation, etc.
So I guess my current plan is to use the render-to-texture method for
the background layers, then have a quad grid for the tiles, and then
simply use different quads for the sprites.
So then I simply have 4 quads for each background layer which resize as
needed. And then draw the quads for the tiles and sprites.
I suppose I could just apply the same matrix to each of the quads to
allow for rotation and scaling etc.
Please correct me where I'm headed in the wrong direct - it's a lot
better to know now than later when it's to late.
hope this helps (and you were able to read through my excessive use of
parentheses)
It helps a lot, believe me for someone who hasn't looked into this in
years its truly a wealth of knowledge.
- lee
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Mac-opengl mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/mac-opengl/email@hidden