代码之家  ›  专栏  ›  技术社区  ›  sum1stolemyname

动态数组作为API函数和Delphi的参数

  •  1
  • sum1stolemyname  · 技术社区  · 15 年前

    在我的应用程序(Delphi2010、OpenGL、WindowsXP)中,我需要读取帧缓冲区可变部分的像素。

    用户通过选择矩形(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;
    

    此函数似乎在前几次尝试时按预期工作,但在对其进行几次调用后,应用程序崩溃,第一次reallocmem的访问冲突为$0000000。

    我尝试使用getmem、finalize和freemm,但是这些函数会导致相同的行为。

    我的设计原则上正确吗?我试着调试它,但找不到故障的原因。 width height 始终具有合理的值,在具有3GB RAM的机器上,分配5-10个30到120kib的块不应该是问题。

    更新

    在调用此函数的过程中,渲染管道可能会绘制一些帧,对象可能会添加到场景中——原则上,应用程序可以执行任何操作,因为当用户决定通过将seelction框拖到画布上来选择要捕获的场景的矩形部分时,会调用此函数。

    以下是我的调试会话的宽度和高度示例

    1. 宽:211高:484尺寸:306372
    2. 宽:162高:395尺寸:191970
    3. 宽度:123高度:275尺寸:101475
    4. 宽:14高:346尺寸:14532

    第四个选择在此会话中失败。在其他会话中,可能会有更成功的选择,其他会话在尝试第二个会话时崩溃,但在第一个会话中没有。

    另一件事:当我注释掉glreadpixels时,不会再出现崩溃。

    2 回复  |  直到 15 年前
        1
  •  1
  •   sum1stolemyname    15 年前

    我终于找到了。

    我对宽度和高度的计算是1,所以我需要将reallocmem行更改为

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

    谢谢你的考虑

        2
  •  1
  •   Ondrej Kelle    15 年前

    是否将像素初始化为零?

    begin
      pixels := nil;
      ...
    

    你有足够的内存吗?这个 example

    • 分配width+1,nheight+1
    • 提到OpenGL在默认情况下可能会将内存与4个字节对齐(请参见 GL_PACK_ALIGNMENT )
    推荐文章