Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Для новичков > Двумерный динамический массив


Автор: Vetos 18.9.2008, 21:19
Здравствуйте программисты!
Появилась проблема в заполнении такого массива
Код

   Texture:array of array of array[0..3] of GLUByte;

Вот заполнение
Код

Bitmap:=TBitmap.Create;
Bitmap.LoadFromFile(filename);
Width:=Bitmap.Width;
Height:=Bitmap.Height;
SetLength(Texture,Width);
   for i:=0 to width-1 do
    for j:=0 to height-1 do
     begin
       SetLength(Texture[i],Height);
       Texture[i,j,0]:=GetRValue(Bitmap.Canvas.Pixels[i,j]);
       Texture[i,j,1]:=GetGValue(Bitmap.Canvas.Pixels[i,j]);
       Texture[i,j,2]:=GetBValue(Bitmap.Canvas.Pixels[i,j]);
       Texture[i,j,3]:=255;
     end;
Bitmap.Free;



Вродебы на первый взгляд все правильно(ну незнаю это на мой взгляд smile ), а вот на экране у меня вместо нормальной текстуры этаже картинка только немного сжатая и повторяющаяся несколько раз(отвлекся).

Однако если явно описать массив
Код

Texture:array[0..255,0..255,0..3]of GLUByte;

Просто картинка 256х256, это я точно знаю))
И опустить строки с SetLength то картинка отображается нормально.
Немогу понять глюка.В приклепленном файле скриншоты.
Если скажете что не по адресу, это в графику, то эт не так, с графикой проблем нет, динамический массив неправильно заполняется, помогите пожалуйсто!!!





Автор: Alexeis 18.9.2008, 21:28
Vetos, вместо массива указателей сделай матрицу

Код

SetLength(Texture, Width, Height);


Должно помочь.

Автор: Vetos 18.9.2008, 21:35
Неа я вначале так и делал, потом хотел тему написать поискал по сайту нашел второй вариант, такая же история, незнаю уже что делать, можно былобы и статический массив сделать но кадрировать текстуры чот не охота))

Автор: Alexeis 18.9.2008, 21:41
Vetos, может быть еще перепутал размеры строк и столбцов. Попробуй наоборот поменять размерности.

Автор: Vetos 18.9.2008, 21:48
Так текстура квадратная я уже и ShowMessage проверял Width и Height. Уже в голову ничего не лезет smile 

Автор: Vetos 18.9.2008, 22:04
Короче я после загрузки массива записывал его в файл, получил два файла с массивами, сравнил их, они идентичны, тоесть все норм, дело в самой OpenGL, чот ненравится ей динамический массив.
 smile 

Автор: CodeMonkey 19.9.2008, 04:41
Учли, что переменная динамического массива - это не указатель на первый элемент данных?
Как передаёте его в функцию?
А как сохраняли массивы? Если в функцию сохранения вы два раза передали одинаковые даные с разных массивов, то (при условии, что в OGL так же передаёте) и разницы при их выводе быть не должно.

Автор: Alexeis 19.9.2008, 09:54
Цитата(CodeMonkey @  19.9.2008,  03:41 Найти цитируемый пост)
Учли, что переменная динамического массива - это не указатель на первый элемент данных?

  Точно! Ведь опенгл ждет что к нему прийдет матрица единым блоком, а не массив указателей на строки. Нужно переписать строки в непрерывный блок в памяти. Примерно так 
Код

procedure TForm1.FormCreate(Sender: TObject);
var
  Texture : array of array of array[0..3] of GLUByte;
  i, j, LSize : Integer;
  pTexture, ptmp : PAnsiChar;
  Width, Height : Integer;
  Bitmap : TBitmap;
begin
  Bitmap:=TBitmap.Create;
  Bitmap.LoadFromFile(filename);
  Width:=Bitmap.Width;
  Height:=Bitmap.Height;
  SetLength(Texture, Width, Height);
  LSize := Height * 4 * sizeof(GLUByte);
  GetMem(pTexture, Width * LSize);
  ptmp := pTexture;
  for i:=0 to width-1 do
  Begin
    SetLength(Texture[i],Height);
    for j:=0 to Height - 1 do
     begin
       Texture[i,j,0]:=GetRValue(Bitmap.Canvas.Pixels[i,j]);
       Texture[i,j,1]:=GetGValue(Bitmap.Canvas.Pixels[i,j]);
       Texture[i,j,2]:=GetBValue(Bitmap.Canvas.Pixels[i,j]);
       Texture[i,j,3]:=255;
     end;
    Move(Texture[i][0], ptmp^, LSize);
    inc(ptmp, LSize);
  End;
  Bitmap.Free;

  // pTexture - указатель на нужную матрицу (не забыть удалить после использоваиня)
end;


Нужная текстура будет в указателе pTexture .

Автор: Vetos 19.9.2008, 20:09
Alexeis, большое спасибо+

Теперь хочу немного разобраться как оно работает smile 

Получается трехмерный массив строится в памяти строкой за строку, я это понял из того что процедура Move копирует участок памяти из Texture в pTmp начиная с LSize. Так получается последовательность, что собсвенно и есть массив.
Если это я правильно понял.

Есть несколько вопросов:

1)Что такое PAnsiChar? Почемуто Ctrl+Левая мыша просто указывает мне на модуль System. Как оно описано?

2)Чем отличается динамический массив от обычного(я имею ввиду в памяти).

3)Что значит удалить pTexture после использования?

Спасибо!

Автор: Alexeis 19.9.2008, 20:25
Цитата(Vetos @  19.9.2008,  19:09 Найти цитируемый пост)
Получается трехмерный массив строится в памяти строкой за строку, я это понял из того что процедура Move копирует участок памяти из Texture в pTmp начиная с LSize. Так получается последовательность, что собсвенно и есть массив.
Если это я правильно понял.

  Ну почти, строка за строкой это двумерный массив, но каждый элемент строки тоже массивчик из 4 элементов, поскольку он не динамической размерности то элементы строки идут непрерывным блоком. Если бы 3я размерность была динамической то каждый элемент строки был бы тоже указателем.

Цитата(Vetos @  19.9.2008,  19:09 Найти цитируемый пост)
1)Что такое PAnsiChar? Почемуто Ctrl+Левая мыша просто указывает мне на модуль System. Как оно описано?

  Простой типизировнный указатель. Указатель на символ. В данном случае удобно интерпретировать байты как символы, потому что над указателями типа  PAnsiChar можно производить арифметические операции (над другими нельзя, нужно дополнительное приведение). Раньше использовали PChar, но это уже не прокатывает в 2009й делфе так как там юникод, потому именно PAnsiChar.
Код

PAnsiChar = ^AnsiChar;


Цитата(Vetos @  19.9.2008,  19:09 Найти цитируемый пост)
2)Чем отличается динамический массив от обычного(я имею ввиду в памяти).

Одномерный динамический массив почти такой же как и простой, элементы идут друг за другом. Статическая матрица, это строки идущие одна за другой, динамическая матрица это массив указателей, каждый из которых указывает на свою строку.

Автор: Vetos 19.9.2008, 20:37
Спасибо smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)