Динамические массивы как параметры для функций API и Delphi - PullRequest
1 голос
/ 26 августа 2010

В моем приложении (Delphi 2010, OpenGL, Windows XP) мне нужно считывать пиксели переменных частей кадрового буфера.

Область интереса вводится пользователем через прямоугольник выбора (x1, y1, x2, y2).

С этими координатами я делаю это:

var
  pixels : PGLUByte; //pointer to unsigned bytes

begin       

 [Transformation of coordinates to Opengl viewport offsets]

 //reserve a block of memory for readpixels to write to
 ReallocMem(pixels, width * height* sizeof(GLUByte)*3); //<<< crash on this line after a few iterations
 if not assigned(pixels) then exit;
 //read the pixels
 glReadPixels(startx, viewport[3] - (starty+height), 
             width , height, 
             GL_RGB, GL_UNSIGNED_BYTE, 
             pixels);

 //Processing of the pixel data follows here...

 //when done, release the memory
 ReallocMem(pixels, 0);
end;

Эта функция, кажется, работает должным образом с первых нескольких попыток, но после нескольких обращений к ней происходит сбой приложения с нарушением прав доступа на уровне $ 0000000 в первом ReallocMem.

Я пытался использовать Getmem, Finalize и Freemem, но эти функции ведут к одинаковому поведению.

Является ли мой дизайн принципиально правильным? Я пытался отладить его, но не смог определить причину проблемы. width и height всегда имеют вероятные значения, и выделение 5-10 блоков размером от 30 до 120 КиБ не должно быть проблемой на машине с 3 ГБ ОЗУ.

Обновление

Между вызовами этой функции конвейер рендеринга может нарисовать несколько кадров, объекты могут быть добавлены на сцену - в принципе все, на что способно приложение, поскольку эта функция вызывается, когда пользователь решил выбрать прямоугольную часть моей сцены для захвата путем перетаскивания окна выбора на холсте.

Вот пример ширины и высоты моего сеанса отладки

  1. ширина: 211 высота: 484 размер: 306372
  2. ширина: 162 высота: 395 размер: 191970
  3. ширина: 123 высота: 275 размер: 101475
  4. ширина: 14 высота: 346 размер: 14532

Четвертый выбор не удался в этой сессии. в другом сеансе были возможны более успешные варианты выбора, другие зависали при попытке второго, но ни одного в первом.

Другое дело: когда я комментирую glReadPixels, больше не происходит сбоев.

Ответы [ 2 ]

1 голос
/ 26 августа 2010

Я все-таки нашел это.

Мои вычисления для ширины и высоты были по одному, поэтому мне нужно было изменить мою строку reallocmem на

ReallocMem(pixels, (width+1) * (height+1) * sizeof(GLUByte)*3);

Спасибо за внимание

1 голос
/ 26 августа 2010

Вы инициализируете пиксели в ноль?

begin
  pixels := nil;
  ...

Вы выделяете достаточно памяти?В этом примере

  • выделяется nWidth + 1, nHeight + 1
  • , где упоминается, что OpenGL может выравнивать память по 4 байта по умолчанию (см. GL_PACK_ALIGNMENT).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...