bitmap as array

  • Follow


Hello all, I am new to opengl. I did the following: starting with a picture
file, say pic.bmp (of pixel 'height' rows and 'width' columns powers of 2)I
first read it into an array GLubyte P[], and 'converted' this to GLubyte A
[3*width*height] which contains exactly all the pixels. I 'converted' this
to
GLubyte A2[height*width][3] and then this to GLubyte A3[height][width][3].
I am surprised to find that I can use either of A1,A2,A3 in making a texture
in glTexImage2D(.....A) where A is any one of these three. Any comments
will be much appreciated.
Ivan.
0
Reply ivan 2/18/2005 1:26:35 PM

ivan danicic wrote:
> Hello all, I am new to opengl. I did the following: starting with a picture
> file, say pic.bmp (of pixel 'height' rows and 'width' columns powers of 2)I
> first read it into an array GLubyte P[], and 'converted' this to GLubyte A
> [3*width*height] which contains exactly all the pixels. I 'converted' this
> to
> GLubyte A2[height*width][3] and then this to GLubyte A3[height][width][3].
> I am surprised to find that I can use either of A1,A2,A3 in making a texture
> in glTexImage2D(.....A) where A is any one of these three. Any comments
> will be much appreciated.
> 

This is really a 'C' question, not OpenGL.

In memory, all arrays are really 2D.

When you declare a 3D array it's the C
compiler which makes "a[x][y][z]" into
"a[x*p*q + y*q + z]" for you.


-- 
<\___/>
/ O O \
\_____/  FTB.    For email, remove my socks.
0
Reply fungus 2/18/2005 2:13:10 PM


ivan danicic wrote:

> Hello all, I am new to opengl.

Well, that has nothing to do with OpenGL, but is more general
programming topic.

> I did the following: starting 
> with a picture file, say pic.bmp (of pixel 'height' rows and
> 'width' columns powers of 2)I first read it into an array
> GLubyte P[], and 'converted' this to GLubyte A
> [3*width*height] which contains exactly all the pixels. I
> ['converted' this
> to
> GLubyte A2[height*width][3] and then this to GLubyte
> A3[height][width][3]. I am surprised to find that I can use
> either of A1,A2,A3 in making a texture in glTexImage2D(.....A)
> where A is any one of these three. Any comments will be much
> appreciated. Ivan.

That's no surprise to me. And it get's clear if you imagine how
those arrays are internally represented in computer memory: As
memory can be thought as this array:

BYTE memory[space];

where space is 2GB (for 32 Bit plattforms) in modern OS (see
virtual memory) any other type of memory setup has to be fit
into this 1D memory. So lets first do it for a simple 4x4 2D
array of scalar values (the actual values are not important, so
I will give them indexed number)

 1   2   3   4
 5   6   7   8
 9  10  11  12
13  14  15  16

This matrix could e.g. be a grayscale image. So how is it setup
in 1D memory. Well you just write it row by row or column by
column, you could also do spirals or anything other, it's just
important to use a well defined convention. So were now looking
at bitmaps. Those are written left->right and then bottom->top
So in 1D this looks like

13 14 15 16 9 10 11 12 5 6 7 8 1 2 3 4

It should be easy to understand, that you could do this with any
amount of dimension. So writing down a 4x4x4x4 array is nothing
more complicated.

If you look on how C defines how multidimensional arrays are to
be setup in memory, then it'd defined that rightmost index has
to increment the fastest. You did a [height][width] and so would
the access of a single element be [y][x]. So the x coordinate is
the fastest incrementing, which matches the BMP format.

Now let's introduce multiple channels AKA colours. It's now
important to know, that there exist different image formats.
There are some in which the colour tuples are packed, or where
several scalar (greyscale) subimages are stored subsequently
which are later merged. For now it's important, that OpenGL
glTexImage2D with one of the standard formats (GL_RGB(A))
expects the pixels as tuples.

Lets again visualize the difference:

This would be the subimages, stored subsequently

 1   2   3   4
 5   6   7   8
 9  10  11  12
13  14  15  16

 1   2   3   4
 5   6   7   8
 9  10  11  12
13  14  15  16

 1   2   3   4
 5   6   7   8
 9  10  11  12
13  14  15  16

for this the C array would be [3][4][4] or in general 
[channels][height][width]

And this are packed pixels (the parentheses are there to show the
data groups)

( 1  1  1) ( 2  2  2) ( 3  3  3) ( 4  4  4)
( 5  5  5) ( 6  6  6) ( 7  7  7) ( 8  8  8)
( 9  9  9) (10 10 10) (11 11 11) (12 12 12)
(13 13 13) (14 14 14) (15 15 15) (16 16 16)

The C array would be [4][4][3] or in general
[channels][height][width] When writing this as 1D alignment of 3
tuples you would do this as [width*height]*[channels] (well
that's 2D, but a tuple introduces a additional dimension). So in
our case [4*4][3]

Now let's summarize: BMPs are l->r, b->t with each pixel being a
packed tuple of 3 colur values (BGR), so this equivalent to the
arrays:

[height][width][3] (2D field of 3 tuples)
[height* width][3] (1D sequence of 3 tuples l->r b->t)
[height* width* 3] (1D sequences of scalars)

However for each of these 3 in the computer's memory they all
look the very same with default compiler settings: tightly
packed. You _can_ say the compiler, that it should arrange
multilinear arrays in a way, that they meet the alignment of the
CPU to increase performance. On most systems this is 4 byte,
however in OpenGL you mostly want an alpha cannel, so you've got
4 tuples. So while aligning 3 tuples may break the code with
multi-dim arrays 4 tuples will see no difference.

If you now give glTexImage the pointer to the beginning of the
memory where the image is stored it does make no difference how
you accessed it as the result looks the same.

But don't be fooled: Other setups won't work with glTexImage.
E.g. if you decide to store the channels per row:

[height][channels][width]

it won't work. At least not out of the box. You could use
glPackAlignment to set a row skip value and apply some tricks to
insert the channels subsequently into a texture.

-- 
Wolfgang Draxinger

0
Reply Wolfgang 2/18/2005 2:38:20 PM

Wolfgang Draxinger wrote:

> ivan danicic wrote:
> 
>> Hello all, I am new to opengl.
> 
> Well, that has nothing to do with OpenGL, but is more general
> programming topic.
> 
>> I did the following: starting
>> with a picture file, say pic.bmp (of pixel 'height' rows and
>> 'width' columns powers of 2)I first read it into an array
>> GLubyte P[], and 'converted' this to GLubyte A
>> [3*width*height] which contains exactly all the pixels. I
>> ['converted' this
>> to
>> GLubyte A2[height*width][3] and then this to GLubyte
>> A3[height][width][3]. I am surprised to find that I can use
>> either of A1,A2,A3 in making a texture in glTexImage2D(.....A)
>> where A is any one of these three. Any comments will be much
>> appreciated. Ivan.
> 
> That's no surprise to me. And it get's clear if you imagine how
> those arrays are internally represented in computer memory: As
> memory can be thought as this array:
> 
> BYTE memory[space];
>
SNIP
> But don't be fooled: Other setups won't work with glTexImage.
> E.g. if you decide to store the channels per row:
> 
> [height][channels][width]
> 
> it won't work. At least not out of the box. You could use
> glPackAlignment to set a row skip value and apply some tricks to
> insert the channels subsequently into a texture.
> 
Hello, I suspected this; however is there not an 'official' array type for
a texture thing which is guaranteed to work for any C compiler? I don't
think C requires arrays to be stored in any particular way though we can be
sure that an array byte[][13] is an array of arrays byte[13] and a pointer
to it is the address of byte[0][13]. Anyway it's nice to know that the
simplest of these arrays is good enough, at least for my c-compiler.Further
comments will still be appreciated.
Ivan.
0
Reply ivan 2/18/2005 5:14:17 PM

ivan danicic wrote:

> Hello, I suspected this; however is there not an 'official'
> array type for a texture thing which is guaranteed to work for
> any C compiler?

Use the good plain 1D array. Also consider, that multi-dim arrays
are syntactically a pain with dynamically allocated memory
(you've to throw in a lot of parentheses to override operator
precedence). And by dealing with image data you will have to use
dynamically allocated memory.

So, when using image data don't bother with C multidimensional
arrays, but just do a

byte *imagedata = malloc(width*height*bytes_per_pixel);//in C

or

byte *imagedata = new byte[width*height*bytes_per_pixel];//in C++

-- 
Wolfgang Draxinger

0
Reply Wolfgang 2/18/2005 6:09:18 PM

Wolfgang Draxinger wrote:
> 
> byte *imagedata = new byte[width*height*bytes_per_pixel];//in C++
> 

Much better:

std::vector<byte>imagedata(width*height*bytes_per_pixel);


-- 
<\___/>
/ O O \
\_____/  FTB.    For email, remove my socks.

Governments, like diapers, should be changed often,
and for the same reason.
0
Reply fungus 2/18/2005 6:59:58 PM

fungus wrote:

> std::vector<byte>imagedata(width*height*bytes_per_pixel);

A bit much overhead for a simple buffer.

-- 
Wolfgang Draxinger

0
Reply Wolfgang 2/18/2005 8:26:29 PM

Wolfgang Draxinger wrote:

> fungus wrote:
> 
>> std::vector<byte>imagedata(width*height*bytes_per_pixel);
> 
> A bit much overhead for a simple buffer.
> 
Hello all, thanks very much for your useful comments. What's this vector?
Looks like c++. Me no like.
Ivan
0
Reply ivan 2/18/2005 10:18:50 PM

fungus wrote:
> In memory, all arrays are really 2D.

1D.

-- 
Dr Jon D Harrop, Flying Frog Consultancy

0
Reply Jon 2/19/2005 12:00:16 AM

Wolfgang Draxinger wrote:
> fungus wrote:
>> std::vector<byte>imagedata(width*height*bytes_per_pixel);
> 
> A bit much overhead for a simple buffer.

Why do you say that?

It will be slower to compile but the code can then be bounds checked easily.

-- 
Dr Jon D Harrop, Flying Frog Consultancy
http://ffconsultancy.com
0
Reply Jon 2/19/2005 12:04:22 AM

Jon Harrop wrote:
> Wolfgang Draxinger wrote:
> 
>>fungus wrote:
>>
>>>std::vector<byte>imagedata(width*height*bytes_per_pixel);
>>
>>A bit much overhead for a simple buffer.
> 

I think you'll find it's exactly the same,
overhead, ie. a pointer to some memory and
a call to malloc.

The advantages of doing it this way, OTOH,
are many.


-- 
<\___/>
/ O O \
\_____/  FTB.    For email, remove my socks.
0
Reply fungus 2/19/2005 12:08:56 AM

fungus wrote:
>> Wolfgang Draxinger wrote:
>>>fungus wrote:
>>>>std::vector<byte>imagedata(width*height*bytes_per_pixel);
>>>A bit much overhead for a simple buffer.
> 
> I think you'll find it's exactly the same,
> overhead, ie. a pointer to some memory and
> a call to malloc.

There's probably a 1 word header giving the number of elements. That's a
small price to pay for the safety it provides though, IMHO. The extra
compile time is probably the main disadvantage.

> The advantages of doing it this way, OTOH,
> are many.

Yes, absolutely. See, even fungus doesn't use char arrays. ;-)

-- 
Dr Jon D Harrop, Flying Frog Consultancy
http://ffconsultancy.com
0
Reply Jon 2/19/2005 12:25:37 AM

Jon Harrop wrote:
>>
>>I think you'll find it's exactly the same,
> 
> There's probably a 1 word header giving the number of elements. That's a
> small price to pay for the safety it provides though, IMHO. The extra
> compile time is probably the main disadvantage.
> 

Ok, I confess...there's probably three pointers in
there. One points to the data (ie. array.begin()),
one points to the end of the array (ie. array.end())
and one points to the end of the allocated memory
(ie. array.begin()+array.capacity()).

> See, even fungus doesn't use char arrays. ;-)
> 

My rule of thumb is that if you use operator new[]
outside of a low level storage class (eg. std::string,
std::vector) then you're _probably_ doing something
wrong.

"Arrays are evil" - the C++ FAQ.


-- 
<\___/>
/ O O \
\_____/  FTB.    For email, remove my socks.

Governments, like diapers, should be changed often,
and for the same reason.
0
Reply fungus 2/19/2005 1:16:32 AM

Jon Harrop wrote:
> fungus wrote:
> 
>>In memory, all arrays are really 2D.
> 
> 
> 1D.
> 

Um, yeah. I meant 1D, obviously.

(But bytes have width!)


-- 
<\___/>
/ O O \
\_____/  FTB.    For email, remove my socks.
0
Reply fungus 2/21/2005 7:37:56 AM

13 Replies
259 Views

(page loaded in 0.149 seconds)

Similiar Articles:


















7/25/2012 9:04:13 AM


Reply: