Re: Test Dynamic Memory
On Dec 14, 7:17 pm, Immortal Nephi <Immortal_Ne...@hotmail.com> wrote:
I agree with you. You should declare and define unsigned char array
to hold bitmap image in the global scope. I would strongly recommend
you to construct array class in your own. Declare unsigned char to
static const inside array class. In another way, you can use pointer
to unsigned char when it uses dynamic memory. You use fstream to
read / load raw bitmap image into dynamic memory. You can use either
choice.
Heap is heaps better for surface data. Global variables are rarely
needed at all and won't work very well on few mobile environments /
platforms (globals and statics are tricky on BREW and SYMBIAN).
I have abstraction for surfaces, where surface class is a reference
(not in C++ sense of the word) to the image data. The surface class
has a pointer to the image data, width, height, stride and format.
That is all information I need to communicate with different API's,
OpenGL; Direct3D, OpenCL and so on. The surface class is just
description of the image data, nothing more. Examples:
1. Create surface from a file
surface* s = surface::create(L"bukkake.jpg"=B4, pixelformat::argb8888);
uint32* image = s->lock<uint32>();
// TODO: do something with image
s->unlock();
s->release();
The pixelformat is complex object which describes the pixelformats
with masks for color components, has type enumeration for components
(uint32, float, half, etc..), fourcc for compressed data and so on and
on. The pixelformat::argb8888 is pre-defined format for convernience
(there are obviously more but that one is very common ;)
This approach reads the file, decodes the bitstream and creates a new
surface object. Pretty obvious. The surface "owns" the data, so the
release() method will deallocate the image.
2. Creating a reference to existing image..
void foo(char* image)
{
// we "know" that the raw data is in RGB565 format
surface* s = surface::create(320, 240, pixelformat::rgb565, image,
320 * sizeof(uint16));
// ... do something ..
s->release();
}
This time around the s->release WON'T free the image data, since this
surface is just describing (=reference) to data elsewhere.
What if we want to create a surface which DOES "own" the image data?
3. Create surface and allocate memory
surface* s = bitmap::create(640, 480, format);
s->release();
And so on. The "API" is same for the surfaces; you can lock them, read
and write to the image data the surface is describing, serialize
(write into file, memory buffer, etc.).. clear the surface, blit it to
other surface (with scaling, filtering, etc).
The surface system supports bitmaps, surfaces, cubemaps, 3d textures,
2d textures, you name it. The code is portable, however, I only have
tested it on OS X, Linux (32 bit and 64 bit), IRIX and Windows (32 bit
and 64 bit). So basically 32 bit and 64 bit, little and big endian
systems are covered.
The "system" might sound complicated, but it's not, really. Simple
inheritance to support different flavors of surfaces.
I have a font system as well, but it's based on textures and unicode
(can render different languages than just Latin). Latin is easy if we
use "char"; just use a look-up-table and we're done. Unicode requires
more eloborate caching scheme since we don't know in advance which
glyphs might be needed.
First, we need to cache the glygps.. for this I use a simple binary
tree for lookup. If we have a cache miss, we need to allocate texels
from existing texture. So we need a surface manager (2D memory
allocator). It's more efficient to use a single texture and spill the
least recently used glyphs out (so I use LRU eviction policy, sue me)
rathen than trying to use more textures.
The cache size (=texture size) is configurable, I usually am very
happy with 512x512 texture, but 2048x2048 would probably never spill
in practical application.
The surface manager does NOT have de-fragmenting, I use fixed tile
size which I determine from the font size. This wastes maybe 5-10% of
texture area but eliminates the need for de-fragmenting so it's a good
tradeoff.
If I were doing application just for Latin character set, a simple
lookup table approach would be much simpler. But I have to support
Japanese, Korean, etc. I don't know those languages, but filenames in
those languages MUST work in the User Interface which is rendered with
OpenGL, so, Unicode font system is a Must.
Speaking of unicode, supporting it with c++ is a bit .. let's not talk
about that.