PDA

View Full Version : Displaying from dynamic arrays



MateeC
25-12-2003, 10:04 AM
Hello! :)

I have this problem:
I load a 100x100 picture from a very simple format (SizeX, SizeY, Colors)
Firstly i had this load procedure, and a static array:


cRGB, cRGBA: Array(.0..100, 0..100.) of Cardinal;

. . .

AssignFile(F, Filename);
Reset(F);

Readln(F, SizeX);
Readln(F, SizeY);

for I := 0 to SizeX do
for J := 0 to SizeY do
begin
Readln(F, cRGB(.I,J.));

if cRGB(.I,J.) = 0 then
cRGBA(.I,J.) := $FF000000 else // for transparency with glAlphaFunc
cRGBA(.I,J.) := cRGB(.I,J.);
end;

Closefile(F);

And drew it with: glDrawPixels(SizeX, SizeY, GL_RGBA, GL_UNSIGNED_BYTE, @cRGBA);
This worked great... but only if the picture was exactly 100x100 pixels large(the array size), otherwise i got a error(if larger) or a distorted picture(if smaller).

Then I searched the google a little, and found out about dynamic arrays (well i'm quite a newbie), and changed the procedure a little:


cRGB, cRGBA: Array of array of Cardinal;

. . .

AssignFile(F, Filename);
Reset(F);

Readln(F, SizeX);
Readln(F, SizeY);

// I think the problem is here: If i set the lengths to SizeX and SizeY
// i get thrown out of the program when variable I reaches SizeX,
// but if length is SizeX+1 the size of the array is 101 not 100 as it should be,
SetLength(cRGB, SizeX+1, SizeY+1);
SetLength(cRGBA, SizeX+1, SizeY+1);

for I := 0 to SizeX do
for J := 0 to SizeY do
begin
Readln(F, cRGB(.I,J.));

if cRGB(.I,J.) = 0 then
cRGBA(.I,J.) := $FF000000 else
cRGBA(.I,J.) := cRGB(.I,J.);
end;

Closefile(F);

And i drew this one with: glDrawPixels(SizeX, SizeY, GL_RGBA, GL_UNSIGNED_BYTE, @cRGBA(. 0,0 .));
If i didn't add (.0,0.) after the array, it just displayed garbage.

So now it displays a distorted image(kind of like the original, but very tilted), but i can't fix it... i tried some things (like setting the length again after the loop, and changeing the Drawpixles parameters,...) but none worked, the closest thing was glDrawPixels(SizeX+3, SizeY, GL_RGBA, GL_UNSIGNED_BYTE, @cRGBA(. 0,0 .)); but it had a diagonal black line, and it was slightly distorted

So can anyone help me :?:

Paulius
25-12-2003, 03:28 PM
Well actually Array(.0..100.) would have 101 elements, because you get elements from 0 to 100 including 0, setlength(myarray, 100) would set the length to 100 witch is less by one than Array(.0..100.).
This distortion happens because a 2D array in memory is actually an array of 1D arrays, so if you, for example, specify a shorter than actual length the beginning of the second drawn line would contain the pixels at the first lines end in the array and so forth.
And why not use [] instead of (..) ?

try
var
cRGB, cRGBA: array of array of Cardinal;

AssignFile(F, Filename);
Reset(F);

Readln(F, SizeX);
Readln(F, SizeY);

SetLength(cRGB, SizeX, SizeY);
SetLength(cRGBA, SizeX, SizeY);

for I := 0 to SizeX-1 do
for J := 0 to SizeY-1 do
begin
Readln(F, cRGB(.I,J.));

if cRGB(.I,J.) = 0 then
cRGBA(.I,J.) := $FF000000
else cRGBA(.I,J.) := cRGB(.I,J.);
end;

Closefile(F);

MateeC
25-12-2003, 08:20 PM
Well i tried that, but it didn't work... Don't have a clue why :?

Here's the entire code (you need DOT for some commands, its avalible at http://www.delphi3d.net/dot)


var
SizeX, SizeY: Integer;
cRGB, cRGBA: Array of array of Cardinal;
F: TextFile;

procedure TForm1.FormCreate(Sender: TObject);
var
I, J: Integer;
begin
Width := 800;
Height := 600;

Context.InitGL;
glViewport(0, 0, 800, 600);

AssignFile(F, 'untitled.pci');
Reset(F);

Readln(F, SizeX);
Readln(F, SizeY);

SetLength(cRGB, SizeX, SizeY);
SetLength(cRGBA, SizeX, SizeY);

for I := 0 to SizeX-1 do
for J := 0 to SizeY-1 do
begin
Readln(F, cRGB(.I,J.));

if cRGB(.I,J.) = 0 then
cRGBA(.I,J.) := $FF000000 else
cRGBA(.I,J.) := cRGB(.I,J.);
end;

Closefile(F);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
glClear(GL_COLOR_BUFFER_BIT);

glBegin(GL_QUADS);
glColor3f(0, 0.5, 0);
glVertex2f(-1, +1);
glVertex2f(+1, +1);
glVertex2f(+1, -1);
glVertex2f(-1, -1);
glEnd();

glEnable(GL_ALPHA_TEST);

glAlphaFunc(GL_Less, 1);
glRasterPos2d(0,0);
glDrawPixels(SizeX, SizeY, GL_RGBA, GL_UNSIGNED_BYTE, @cRGBa(.0,0.));

Context.PageFlip;

glDisable(GL_ALPHA_TEST);
end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Key = VK_ESCAPE then Application.terminate;
end;

end.


And here is what it draws, and what its supposed to:
http://freeweb.siol.net/dpotoc2/DJUK/OGL.PNG

Useless Hacker
31-12-2003, 09:30 PM
Why are you using (. and .) instead of [ and ]? :?

Ultra
01-01-2004, 03:54 AM
You can use (. and .) instead of [] :shock: !!!

(Probably the least interesting post ever!) :wink:


EDIT:
After actually looking at the question I realized that I had a similar problem. So if anyone is smart enough to give a better answer than I it's appreciated. :wink:

MateeC
01-01-2004, 03:05 PM
:lol:
I use (. instead of [ because i have a localized keyboard, which (i dont know why) doesent want to write the [
it does write the ] but not the [, so i just got used to (. .)
:lol:

Ok now that thats cleared... can please someone answer the question :)

Thanks!!

Alimonster
05-01-2004, 10:03 AM
I'll give you an answer to this question sometime later today, hopefully, after work. In the meantime, I have to ask why you don't just use a targa (.tga) image instead of your own custom format? DOT has built-in support for tga images, so you would be saving yourself some bother.

MateeC
05-01-2004, 07:48 PM
Hi!
Thanks Alimonster.... I didnt really notice that before... I like it, *but* is there a way, to change the image data in runtime, and how do i apply alpha chanells... as i recall targas can save alpha chanells right into the file, right

Another question:
I'm still a beginer in opengl, and i'm using it for 2d purposes,
so, is glDrawPixels the best approach, or is there a better way?

oh... and I still would like to know how why that program i posted doesent work... if not for anything else, for my curiosity

Thanks for the answers! :)

Paulius
05-01-2004, 10:24 PM
is there a way, to change the image data in runtime
There should be a function to get a pointer to what was your cRGBA. You shouldnt recreate texture data at runtime though, better make some textures at startup to avoid huge slowdowns.

targas can save alpha chanells right into the file, right
Right you are, 32bit tga files have an alpha channel.

is glDrawPixels the best approach, or is there a better way?
glDrawPixels is SLOW, it's much better to use texture mapped quads.

Alimonster
05-01-2004, 11:20 PM
I've looked at that source and I can't spot the problem just now. Could you send me the file you're trying to load (untitled.pci) to akeys "at" icscotland "dot" net, please? I want to see if I can display the thing properly in a quick test cradle to make sure it's not the image itself that's faulty.

I had a look inside the tga loader of DOT. It looks like the property "Data" allows you access to the pixels, and the "header" property gives info about the image (width, height, etc.). It shouldn't be too difficult to modify the pixels with that info. You should be able to typecast the Data property then modify the pixels directly, I'd assume (without having used DOT myself).