<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
Hej,
<p>I made a object factory to combine vtk and qt. Now we got a problem
under NT4.0.
<br>My object factory replaces vtkRenderWindow, vtkRenderWindowInteractor,
etc....
<br>and VTK (3.2) is build as one vtkdll.dll (no changes)
<p>The problem:
<br>We create a vtkRenderWindow and add vtkCubeSource.
<br>If we try to pick the cube (pressing 'p') we got a memory heap error.
<br>The same programm on an SGI works fine and the same programm under
NT without my objectfactory
<br>works fine, too.
<p>The reason is, we can't execute <tt>renderer->GetZ(150, 400);</tt> under
NT.
<p>Here is the code from vtkRenderer:
<blockquote><tt>float vtkRenderer::GetZ (int x, int y)</tt>
<br><tt>{</tt>
<br><tt> float *zPtr;</tt>
<br><tt> float z;</tt>
<p><tt> zPtr = this->RenderWindow->GetZbufferData (x, y, x, y);</tt>
<br><tt> if (zPtr)</tt>
<br><tt> {</tt>
<br><tt> z = *zPtr;</tt>
<br><tt> delete [] zPtr;</tt>
<br><tt> }</tt>
<br><tt> else</tt>
<br><tt> {</tt>
<br><tt> z = 1.0;</tt>
<br><tt> }</tt>
<br><tt> return z;</tt>
<br><tt>}</tt></blockquote>
and the corresponding method of my QGLWindow (its a one to one copy from
vtkopenglrenderwindow resp. vtkwin32renderwindow):
<blockquote><tt>float *vtkQGLRenderWindow::GetZbufferData( int x1, int
y1, int x2, int y2 )</tt>
<br><tt>{</tt>
<br><tt> int
y_low, y_hi;</tt>
<br><tt> int
x_low, x_hi;</tt>
<br><tt> int
width, height;</tt>
<br><tt> float
*z_data = NULL;</tt>
<p><tt> // set the current window</tt>
<br><tt> this->MakeCurrent();</tt>
<p><tt> if (y1 < y2)</tt>
<br><tt> {</tt>
<br><tt> y_low = y1;</tt>
<br><tt> y_hi = y2;</tt>
<br><tt> }</tt>
<br><tt> else</tt>
<br><tt> {</tt>
<br><tt> y_low = y2;</tt>
<br><tt> y_hi = y1;</tt>
<br><tt> }</tt>
<p><tt> if (x1 < x2)</tt>
<br><tt> {</tt>
<br><tt> x_low = x1;</tt>
<br><tt> x_hi = x2;</tt>
<br><tt> }</tt>
<br><tt> else</tt>
<br><tt> {</tt>
<br><tt> x_low = x2;</tt>
<br><tt> x_hi = x1;</tt>
<br><tt> }</tt>
<p><tt> width = abs(x2 - x1)+1;</tt>
<br><tt> height = abs(y2 - y1)+1;</tt>
<p><tt> z_data = new float[width*height];</tt>
<p><tt> // Turn of texturing in case it is on - some drivers have
a problem</tt>
<br><tt> // getting / setting pixels with texturing enabled.</tt>
<br><tt> glDisable( GL_TEXTURE_2D );</tt>
<p><tt> glPixelStorei( GL_PACK_ALIGNMENT, 1 );</tt>
<br><tt> glReadPixels( x_low, y_low,</tt>
<br><tt> width, height,</tt>
<br><tt> GL_DEPTH_COMPONENT, GL_FLOAT,</tt>
<br><tt> z_data );</tt>
<p><tt> return z_data;</tt>
<br><tt>}</tt></blockquote>
Why can't we execute "<tt>renderer->GetZ (150, 400);"?</tt>
<p>The renderwindow was created in the application and the renderer is
created in the vtkdll.dll.
<br>The renderwindow allocates memory "<tt>z_data = new float[width*height]"</tt>
but the renderer
<br>isn't allowed to free the memory "<tt>delete [] zPtr;"</tt>. My solution
was that I add a method NewMemory
<br>in the vtkObjectFactory which allocates memory on the heap of the dll
and recompile vtkdll.dll.
<blockquote><tt>char *vtkObjectFactory::NewMemory(int size)</tt>
<br><tt>{</tt>
<br><tt> return new char[size];</tt>
<br><tt>}</tt></blockquote>
I had to remove all memory allocations by:
<blockquote><tt>#ifdef _WIN32</tt>
<br><tt> z_data = (float*)vtkObjectFactory::NewMemory(sizeof(float)*width*height);</tt>
<br><tt>#else</tt>
<br><tt> z_data = new float[width*height];</tt>
<br><tt>#endif</tt></blockquote>
Now all works fine, but I had to create my own VTKdll.dll...
<br>
<p>My questions:
<ul>
<li>
Is there a way to allocate memory which can be freed from an other dll?</li>
<li>
Is there a similar problem with shared libraries on SGIs?</li>
<li>
Is there a solution without changing code from vtk3.2?</li>
</ul>
<p><br>Carsten</html>