You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1303 lines
26 KiB
1303 lines
26 KiB
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: $RCSfile: vtkOpenGLRenderWindow.cxx,v $
|
|
|
|
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
|
|
All rights reserved.
|
|
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
|
|
|
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
PURPOSE. See the above copyright notice for more information.
|
|
|
|
=========================================================================*/
|
|
#include "vtkOpenGLRenderWindow.h"
|
|
#include "vtkOpenGLRenderer.h"
|
|
#include "vtkOpenGLProperty.h"
|
|
#include "vtkOpenGLTexture.h"
|
|
#include "vtkOpenGLCamera.h"
|
|
#include "vtkOpenGLLight.h"
|
|
#include "vtkOpenGLActor.h"
|
|
#include "vtkOpenGLPolyDataMapper.h"
|
|
#include "vtkIdList.h"
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkFloatArray.h"
|
|
#include "vtkUnsignedCharArray.h"
|
|
|
|
#ifndef VTK_IMPLEMENT_MESA_CXX
|
|
vtkCxxRevisionMacro(vtkOpenGLRenderWindow, "$Revision: 1.68 $");
|
|
#endif
|
|
|
|
#define MAX_LIGHTS 8
|
|
|
|
// Initialize static member that controls global maximum number of multisamples
|
|
static int vtkOpenGLRenderWindowGlobalMaximumNumberOfMultiSamples = 8;
|
|
|
|
void vtkOpenGLRenderWindow::SetGlobalMaximumNumberOfMultiSamples(int val)
|
|
{
|
|
if (val == vtkOpenGLRenderWindowGlobalMaximumNumberOfMultiSamples) return;
|
|
vtkOpenGLRenderWindowGlobalMaximumNumberOfMultiSamples = val;
|
|
}
|
|
|
|
int vtkOpenGLRenderWindow::GetGlobalMaximumNumberOfMultiSamples()
|
|
{
|
|
return vtkOpenGLRenderWindowGlobalMaximumNumberOfMultiSamples;
|
|
}
|
|
|
|
vtkOpenGLRenderWindow::vtkOpenGLRenderWindow()
|
|
{
|
|
this->MultiSamples = vtkOpenGLRenderWindowGlobalMaximumNumberOfMultiSamples;
|
|
this->TextureResourceIds = vtkIdList::New();
|
|
if ( this->WindowName )
|
|
delete [] this->WindowName;
|
|
this->WindowName = new char[strlen("Visualization Toolkit - OpenGL")+1];
|
|
strcpy( this->WindowName, "Visualization Toolkit - OpenGL" );
|
|
}
|
|
|
|
// free up memory & close the window
|
|
vtkOpenGLRenderWindow::~vtkOpenGLRenderWindow()
|
|
{
|
|
this->TextureResourceIds->Delete();
|
|
}
|
|
|
|
// Update system if needed due to stereo rendering.
|
|
void vtkOpenGLRenderWindow::StereoUpdate(void)
|
|
{
|
|
// if stereo is on and it wasn't before
|
|
if (this->StereoRender && (!this->StereoStatus))
|
|
{
|
|
switch (this->StereoType)
|
|
{
|
|
case VTK_STEREO_CRYSTAL_EYES:
|
|
// not clear this is supposed to be empty,
|
|
// but it has been that way forever.
|
|
break;
|
|
case VTK_STEREO_RED_BLUE:
|
|
this->StereoStatus = 1;
|
|
break;
|
|
case VTK_STEREO_ANAGLYPH:
|
|
this->StereoStatus = 1;
|
|
break;
|
|
case VTK_STEREO_DRESDEN:
|
|
this->StereoStatus = 1;
|
|
break;
|
|
case VTK_STEREO_INTERLACED:
|
|
this->StereoStatus = 1;
|
|
}
|
|
}
|
|
else if ((!this->StereoRender) && this->StereoStatus)
|
|
{
|
|
switch (this->StereoType)
|
|
{
|
|
case VTK_STEREO_CRYSTAL_EYES:
|
|
this->StereoStatus = 0;
|
|
break;
|
|
case VTK_STEREO_RED_BLUE:
|
|
this->StereoStatus = 0;
|
|
break;
|
|
case VTK_STEREO_ANAGLYPH:
|
|
this->StereoStatus = 0;
|
|
break;
|
|
case VTK_STEREO_DRESDEN:
|
|
this->StereoStatus = 0;
|
|
break;
|
|
case VTK_STEREO_INTERLACED:
|
|
this->StereoStatus = 0;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void vtkOpenGLRenderWindow::OpenGLInit()
|
|
{
|
|
glMatrixMode( GL_MODELVIEW );
|
|
glDepthFunc( GL_LEQUAL );
|
|
glEnable( GL_DEPTH_TEST );
|
|
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
|
|
|
|
// initialize blending for transparency
|
|
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
|
glEnable(GL_BLEND);
|
|
|
|
if (this->PointSmoothing)
|
|
{
|
|
glEnable(GL_POINT_SMOOTH);
|
|
}
|
|
else
|
|
{
|
|
glDisable(GL_POINT_SMOOTH);
|
|
}
|
|
|
|
if (this->LineSmoothing)
|
|
{
|
|
glEnable(GL_LINE_SMOOTH);
|
|
}
|
|
else
|
|
{
|
|
glDisable(GL_LINE_SMOOTH);
|
|
}
|
|
|
|
if (this->PolygonSmoothing)
|
|
{
|
|
glEnable(GL_POLYGON_SMOOTH);
|
|
}
|
|
else
|
|
{
|
|
glDisable(GL_POLYGON_SMOOTH);
|
|
}
|
|
|
|
glEnable(GL_NORMALIZE);
|
|
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
|
|
}
|
|
|
|
|
|
void vtkOpenGLRenderWindow::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os,indent);
|
|
|
|
os << indent << "MultiSamples: " << this->MultiSamples << "\n";
|
|
}
|
|
|
|
int vtkOpenGLRenderWindow::GetDepthBufferSize()
|
|
{
|
|
GLint size;
|
|
|
|
if ( this->Mapped )
|
|
{
|
|
this->MakeCurrent();
|
|
size = 0;
|
|
glGetIntegerv( GL_DEPTH_BITS, &size );
|
|
return (int) size;
|
|
}
|
|
else
|
|
{
|
|
vtkDebugMacro(<< "Window is not mapped yet!" );
|
|
return 24;
|
|
}
|
|
}
|
|
|
|
unsigned char* vtkOpenGLRenderWindow::GetPixelData(int x1, int y1,
|
|
int x2, int y2,
|
|
int front)
|
|
{
|
|
int y_low, y_hi;
|
|
int x_low, x_hi;
|
|
|
|
if (y1 < y2)
|
|
{
|
|
y_low = y1;
|
|
y_hi = y2;
|
|
}
|
|
else
|
|
{
|
|
y_low = y2;
|
|
y_hi = y1;
|
|
}
|
|
|
|
if (x1 < x2)
|
|
{
|
|
x_low = x1;
|
|
x_hi = x2;
|
|
}
|
|
else
|
|
{
|
|
x_low = x2;
|
|
x_hi = x1;
|
|
}
|
|
|
|
unsigned char *data =
|
|
new unsigned char[(x_hi - x_low + 1)*(y_hi - y_low + 1)*3];
|
|
this->GetPixelData(x1, y1, x2, y2, front, data);
|
|
return data;
|
|
}
|
|
|
|
int vtkOpenGLRenderWindow::GetPixelData(int x1, int y1,
|
|
int x2, int y2,
|
|
int front,
|
|
vtkUnsignedCharArray* data)
|
|
{
|
|
int y_low, y_hi;
|
|
int x_low, x_hi;
|
|
|
|
if (y1 < y2)
|
|
{
|
|
y_low = y1;
|
|
y_hi = y2;
|
|
}
|
|
else
|
|
{
|
|
y_low = y2;
|
|
y_hi = y1;
|
|
}
|
|
|
|
if (x1 < x2)
|
|
{
|
|
x_low = x1;
|
|
x_hi = x2;
|
|
}
|
|
else
|
|
{
|
|
x_low = x2;
|
|
x_hi = x1;
|
|
}
|
|
|
|
int width = abs(x_hi - x_low) + 1;
|
|
int height = abs(y_hi - y_low) + 1;
|
|
int size = 3*width*height;
|
|
|
|
if ( data->GetMaxId()+1 != size)
|
|
{
|
|
vtkDebugMacro("Resizing array.");
|
|
data->SetNumberOfComponents(3);
|
|
data->SetNumberOfValues(size);
|
|
}
|
|
return this->GetPixelData(x1, y1, x2, y2, front, data->GetPointer(0));
|
|
|
|
}
|
|
|
|
int vtkOpenGLRenderWindow::GetPixelData(int x1, int y1,
|
|
int x2, int y2,
|
|
int front, unsigned char* data)
|
|
{
|
|
int y_low, y_hi;
|
|
int x_low, x_hi;
|
|
|
|
// set the current window
|
|
this->MakeCurrent();
|
|
|
|
if (y1 < y2)
|
|
{
|
|
y_low = y1;
|
|
y_hi = y2;
|
|
}
|
|
else
|
|
{
|
|
y_low = y2;
|
|
y_hi = y1;
|
|
}
|
|
|
|
if (x1 < x2)
|
|
{
|
|
x_low = x1;
|
|
x_hi = x2;
|
|
}
|
|
else
|
|
{
|
|
x_low = x2;
|
|
x_hi = x1;
|
|
}
|
|
|
|
// Must clear previous errors first.
|
|
while(glGetError() != GL_NO_ERROR);
|
|
|
|
if (front)
|
|
{
|
|
glReadBuffer(GL_FRONT);
|
|
}
|
|
else
|
|
{
|
|
glReadBuffer(GL_BACK);
|
|
}
|
|
|
|
glDisable( GL_SCISSOR_TEST );
|
|
|
|
#if defined(sparc) && !defined(GL_VERSION_1_2)
|
|
// We need to read the image data one row at a time and convert it
|
|
// from RGBA to RGB to get around a bug in Sun OpenGL 1.1
|
|
long xloop, yloop;
|
|
unsigned char *buffer;
|
|
unsigned char *p_data = NULL;
|
|
|
|
buffer = new unsigned char [4*(x_hi - x_low + 1)];
|
|
p_data = data;
|
|
for (yloop = y_low; yloop <= y_hi; yloop++)
|
|
{
|
|
// read in a row of pixels
|
|
glReadPixels(x_low,yloop,(x_hi-x_low+1),1,
|
|
GL_RGBA, GL_UNSIGNED_BYTE, buffer);
|
|
for (xloop = 0; xloop <= x_hi-x_low; xloop++)
|
|
{
|
|
*p_data = buffer[xloop*4]; p_data++;
|
|
*p_data = buffer[xloop*4+1]; p_data++;
|
|
*p_data = buffer[xloop*4+2]; p_data++;
|
|
}
|
|
}
|
|
|
|
delete [] buffer;
|
|
#else
|
|
// If the Sun bug is ever fixed, then we could use the following
|
|
// technique which provides a vast speed improvement on the SGI
|
|
|
|
// Turn of texturing in case it is on - some drivers have a problem
|
|
// getting / setting pixels with texturing enabled.
|
|
glDisable( GL_TEXTURE_2D );
|
|
|
|
// Calling pack alignment ensures that we can grab the any size window
|
|
glPixelStorei( GL_PACK_ALIGNMENT, 1 );
|
|
glReadPixels(x_low, y_low, x_hi-x_low+1, y_hi-y_low+1, GL_RGB,
|
|
GL_UNSIGNED_BYTE, data);
|
|
#endif
|
|
|
|
if (glGetError() != GL_NO_ERROR)
|
|
{
|
|
return VTK_ERROR;
|
|
}
|
|
else
|
|
{
|
|
return VTK_OK;
|
|
}
|
|
|
|
}
|
|
|
|
int vtkOpenGLRenderWindow::SetPixelData(int x1, int y1, int x2, int y2,
|
|
vtkUnsignedCharArray *data, int front)
|
|
{
|
|
int y_low, y_hi;
|
|
int x_low, x_hi;
|
|
|
|
if (y1 < y2)
|
|
{
|
|
|
|
y_low = y1;
|
|
y_hi = y2;
|
|
}
|
|
else
|
|
{
|
|
y_low = y2;
|
|
y_hi = y1;
|
|
}
|
|
|
|
if (x1 < x2)
|
|
{
|
|
x_low = x1;
|
|
x_hi = x2;
|
|
}
|
|
else
|
|
{
|
|
x_low = x2;
|
|
x_hi = x1;
|
|
}
|
|
|
|
int width = abs(x_hi - x_low) + 1;
|
|
int height = abs(y_hi - y_low) + 1;
|
|
int size = 3*width*height;
|
|
|
|
if ( data->GetMaxId()+1 != size)
|
|
{
|
|
vtkErrorMacro("Buffer is of wrong size.");
|
|
return VTK_ERROR;
|
|
}
|
|
return this->SetPixelData(x1, y1, x2, y2, data->GetPointer(0), front);
|
|
|
|
}
|
|
|
|
int vtkOpenGLRenderWindow::SetPixelData(int x1, int y1, int x2, int y2,
|
|
unsigned char *data, int front)
|
|
{
|
|
int y_low, y_hi;
|
|
int x_low, x_hi;
|
|
|
|
// set the current window
|
|
this->MakeCurrent();
|
|
|
|
// Error checking
|
|
// Must clear previous errors first.
|
|
while(glGetError() != GL_NO_ERROR);
|
|
|
|
if (front)
|
|
{
|
|
glDrawBuffer(GL_FRONT);
|
|
}
|
|
else
|
|
{
|
|
glDrawBuffer(GL_BACK);
|
|
}
|
|
|
|
if (y1 < y2)
|
|
{
|
|
|
|
y_low = y1;
|
|
y_hi = y2;
|
|
}
|
|
else
|
|
{
|
|
y_low = y2;
|
|
y_hi = y1;
|
|
}
|
|
|
|
if (x1 < x2)
|
|
{
|
|
x_low = x1;
|
|
x_hi = x2;
|
|
}
|
|
else
|
|
{
|
|
x_low = x2;
|
|
x_hi = x1;
|
|
}
|
|
|
|
glDisable( GL_SCISSOR_TEST );
|
|
|
|
#if defined(sparc) && !defined(GL_VERSION_1_2)
|
|
// We need to read the image data one row at a time and convert it
|
|
// from RGBA to RGB to get around a bug in Sun OpenGL 1.1
|
|
long xloop, yloop;
|
|
unsigned char *buffer;
|
|
unsigned char *p_data = NULL;
|
|
|
|
buffer = new unsigned char [4*(x_hi - x_low + 1)];
|
|
|
|
// now write the binary info one row at a time
|
|
glDisable(GL_BLEND);
|
|
p_data = data;
|
|
for (yloop = y_low; yloop <= y_hi; yloop++)
|
|
{
|
|
for (xloop = 0; xloop <= x_hi - x_low; xloop++)
|
|
{
|
|
buffer[xloop*4] = *p_data; p_data++;
|
|
buffer[xloop*4+1] = *p_data; p_data++;
|
|
buffer[xloop*4+2] = *p_data; p_data++;
|
|
buffer[xloop*4+3] = 0xff;
|
|
}
|
|
/* write out a row of pixels */
|
|
glMatrixMode( GL_MODELVIEW );
|
|
glPushMatrix();
|
|
glLoadIdentity();
|
|
glMatrixMode( GL_PROJECTION );
|
|
glPushMatrix();
|
|
glLoadIdentity();
|
|
glRasterPos3f( (2.0 * (GLfloat)(x_low) / this->Size[0] - 1),
|
|
(2.0 * (GLfloat)(yloop) / this->Size[1] - 1),
|
|
-1.0 );
|
|
glMatrixMode( GL_PROJECTION );
|
|
glPopMatrix();
|
|
glMatrixMode( GL_MODELVIEW );
|
|
glPopMatrix();
|
|
|
|
glDrawPixels((x_hi-x_low+1),1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
|
|
}
|
|
|
|
// This seems to be necessary for the image to show up
|
|
glFlush();
|
|
|
|
glEnable(GL_BLEND);
|
|
#else
|
|
// If the Sun bug is ever fixed, then we could use the following
|
|
// technique which provides a vast speed improvement on the SGI
|
|
|
|
// Turn of texturing in case it is on - some drivers have a problem
|
|
// getting / setting pixels with texturing enabled.
|
|
glDisable( GL_TEXTURE_2D );
|
|
|
|
// now write the binary info
|
|
glMatrixMode( GL_MODELVIEW );
|
|
glPushMatrix();
|
|
glLoadIdentity();
|
|
glMatrixMode( GL_PROJECTION );
|
|
glPushMatrix();
|
|
glLoadIdentity();
|
|
glRasterPos3f( (2.0 * (GLfloat)(x_low) / this->Size[0] - 1),
|
|
(2.0 * (GLfloat)(y_low) / this->Size[1] - 1),
|
|
-1.0 );
|
|
glMatrixMode( GL_PROJECTION );
|
|
glPopMatrix();
|
|
glMatrixMode( GL_MODELVIEW );
|
|
glPopMatrix();
|
|
|
|
glViewport(0,0, this->Size[0], this->Size[1]);
|
|
glPixelStorei( GL_UNPACK_ALIGNMENT, 1);
|
|
glDisable(GL_BLEND);
|
|
glDrawPixels((x_hi-x_low+1), (y_hi - y_low + 1),
|
|
GL_RGB, GL_UNSIGNED_BYTE, data);
|
|
glEnable(GL_BLEND);
|
|
|
|
// This seems to be necessary for the image to show up
|
|
glFlush();
|
|
#endif
|
|
|
|
if (glGetError() != GL_NO_ERROR)
|
|
{
|
|
return VTK_ERROR;
|
|
}
|
|
else
|
|
{
|
|
return VTK_OK;
|
|
}
|
|
}
|
|
|
|
float* vtkOpenGLRenderWindow::GetRGBAPixelData(int x1, int y1, int x2, int y2,
|
|
int front)
|
|
{
|
|
|
|
int y_low, y_hi;
|
|
int x_low, x_hi;
|
|
int width, height;
|
|
|
|
if (y1 < y2)
|
|
{
|
|
y_low = y1;
|
|
y_hi = y2;
|
|
}
|
|
else
|
|
{
|
|
y_low = y2;
|
|
y_hi = y1;
|
|
}
|
|
|
|
if (x1 < x2)
|
|
{
|
|
x_low = x1;
|
|
x_hi = x2;
|
|
}
|
|
else
|
|
{
|
|
x_low = x2;
|
|
x_hi = x1;
|
|
}
|
|
|
|
width = abs(x_hi - x_low) + 1;
|
|
height = abs(y_hi - y_low) + 1;
|
|
|
|
float *data = new float[ (width*height*4) ];
|
|
this->GetRGBAPixelData(x1, y1, x2, y2, front, data);
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
int vtkOpenGLRenderWindow::GetRGBAPixelData(int x1, int y1, int x2, int y2,
|
|
int front, vtkFloatArray* data)
|
|
{
|
|
int y_low, y_hi;
|
|
int x_low, x_hi;
|
|
int width, height;
|
|
|
|
if (y1 < y2)
|
|
{
|
|
y_low = y1;
|
|
y_hi = y2;
|
|
}
|
|
else
|
|
{
|
|
y_low = y2;
|
|
y_hi = y1;
|
|
}
|
|
|
|
if (x1 < x2)
|
|
{
|
|
x_low = x1;
|
|
x_hi = x2;
|
|
}
|
|
else
|
|
{
|
|
x_low = x2;
|
|
x_hi = x1;
|
|
}
|
|
|
|
width = abs(x_hi - x_low) + 1;
|
|
height = abs(y_hi - y_low) + 1;
|
|
|
|
int size = 4*width*height;
|
|
|
|
if ( data->GetMaxId()+1 != size)
|
|
{
|
|
vtkDebugMacro("Resizing array.");
|
|
data->SetNumberOfComponents(4);
|
|
data->SetNumberOfValues(size);
|
|
}
|
|
return this->GetRGBAPixelData(x1, y1, x2, y2, front, data->GetPointer(0));
|
|
|
|
}
|
|
|
|
int vtkOpenGLRenderWindow::GetRGBAPixelData(int x1, int y1, int x2, int y2,
|
|
int front, float* data)
|
|
{
|
|
int y_low, y_hi;
|
|
int x_low, x_hi;
|
|
int width, height;
|
|
|
|
// set the current window
|
|
this->MakeCurrent();
|
|
|
|
if (y1 < y2)
|
|
{
|
|
y_low = y1;
|
|
y_hi = y2;
|
|
}
|
|
else
|
|
{
|
|
y_low = y2;
|
|
y_hi = y1;
|
|
}
|
|
|
|
if (x1 < x2)
|
|
{
|
|
x_low = x1;
|
|
x_hi = x2;
|
|
}
|
|
else
|
|
{
|
|
x_low = x2;
|
|
x_hi = x1;
|
|
}
|
|
|
|
// Error checking
|
|
// Must clear previous errors first.
|
|
while(glGetError() != GL_NO_ERROR);
|
|
|
|
if (front)
|
|
{
|
|
glReadBuffer(GL_FRONT);
|
|
}
|
|
else
|
|
{
|
|
glReadBuffer(GL_BACK);
|
|
}
|
|
|
|
width = abs(x_hi - x_low) + 1;
|
|
height = abs(y_hi - y_low) + 1;
|
|
|
|
|
|
// Turn of texturing in case it is on - some drivers have a problem
|
|
// getting / setting pixels with texturing enabled.
|
|
glDisable( GL_TEXTURE_2D );
|
|
|
|
glPixelStorei( GL_PACK_ALIGNMENT, 1 );
|
|
glReadPixels( x_low, y_low, width, height, GL_RGBA, GL_FLOAT, data);
|
|
|
|
if (glGetError() != GL_NO_ERROR)
|
|
{
|
|
return VTK_ERROR;
|
|
}
|
|
else
|
|
{
|
|
return VTK_OK;
|
|
}
|
|
}
|
|
|
|
void vtkOpenGLRenderWindow::ReleaseRGBAPixelData(float *data)
|
|
{
|
|
delete[] data;
|
|
}
|
|
|
|
int vtkOpenGLRenderWindow::SetRGBAPixelData(int x1, int y1, int x2, int y2,
|
|
vtkFloatArray *data, int front,
|
|
int blend)
|
|
{
|
|
int y_low, y_hi;
|
|
int x_low, x_hi;
|
|
int width, height;
|
|
|
|
if (y1 < y2)
|
|
{
|
|
y_low = y1;
|
|
y_hi = y2;
|
|
}
|
|
else
|
|
{
|
|
y_low = y2;
|
|
y_hi = y1;
|
|
}
|
|
|
|
if (x1 < x2)
|
|
{
|
|
x_low = x1;
|
|
x_hi = x2;
|
|
}
|
|
else
|
|
{
|
|
x_low = x2;
|
|
x_hi = x1;
|
|
}
|
|
|
|
width = abs(x_hi-x_low) + 1;
|
|
height = abs(y_hi-y_low) + 1;
|
|
|
|
int size = 4*width*height;
|
|
if ( data->GetMaxId()+1 != size )
|
|
{
|
|
vtkErrorMacro("Buffer is of wrong size.");
|
|
return VTK_ERROR;
|
|
}
|
|
|
|
return this->SetRGBAPixelData(x1, y1, x2, y2, data->GetPointer(0), front,
|
|
blend);
|
|
}
|
|
|
|
int vtkOpenGLRenderWindow::SetRGBAPixelData(int x1, int y1, int x2, int y2,
|
|
float *data, int front, int blend)
|
|
{
|
|
int y_low, y_hi;
|
|
int x_low, x_hi;
|
|
int width, height;
|
|
|
|
// set the current window
|
|
this->MakeCurrent();
|
|
|
|
// Error checking
|
|
// Must clear previous errors first.
|
|
while(glGetError() != GL_NO_ERROR);
|
|
|
|
if (front)
|
|
{
|
|
glDrawBuffer(GL_FRONT);
|
|
}
|
|
else
|
|
{
|
|
glDrawBuffer(GL_BACK);
|
|
}
|
|
|
|
if (y1 < y2)
|
|
{
|
|
y_low = y1;
|
|
y_hi = y2;
|
|
}
|
|
else
|
|
{
|
|
y_low = y2;
|
|
y_hi = y1;
|
|
}
|
|
|
|
if (x1 < x2)
|
|
{
|
|
x_low = x1;
|
|
x_hi = x2;
|
|
}
|
|
else
|
|
{
|
|
x_low = x2;
|
|
x_hi = x1;
|
|
}
|
|
|
|
width = abs(x_hi-x_low) + 1;
|
|
height = abs(y_hi-y_low) + 1;
|
|
|
|
/* write out a row of pixels */
|
|
glDisable( GL_SCISSOR_TEST );
|
|
glMatrixMode( GL_MODELVIEW );
|
|
glPushMatrix();
|
|
glLoadIdentity();
|
|
glMatrixMode( GL_PROJECTION );
|
|
glPushMatrix();
|
|
glLoadIdentity();
|
|
glRasterPos3f( (2.0 * (GLfloat)(x_low) / this->Size[0] - 1),
|
|
(2.0 * (GLfloat)(y_low) / this->Size[1] - 1),
|
|
-1.0 );
|
|
glMatrixMode( GL_PROJECTION );
|
|
glPopMatrix();
|
|
glMatrixMode( GL_MODELVIEW );
|
|
glPopMatrix();
|
|
|
|
glPixelStorei( GL_UNPACK_ALIGNMENT, 1);
|
|
|
|
if (!blend)
|
|
{
|
|
glDisable(GL_BLEND);
|
|
glDrawPixels( width, height, GL_RGBA, GL_FLOAT, data);
|
|
glEnable(GL_BLEND);
|
|
}
|
|
else
|
|
{
|
|
glDrawPixels( width, height, GL_RGBA, GL_FLOAT, data);
|
|
}
|
|
|
|
// This seems to be necessary for the image to show up
|
|
glFlush();
|
|
|
|
if (glGetError() != GL_NO_ERROR)
|
|
{
|
|
return VTK_ERROR;
|
|
}
|
|
else
|
|
{
|
|
return VTK_OK;
|
|
}
|
|
}
|
|
|
|
unsigned char *vtkOpenGLRenderWindow::GetRGBACharPixelData(int x1, int y1,
|
|
int x2, int y2,
|
|
int front)
|
|
{
|
|
int y_low, y_hi;
|
|
int x_low, x_hi;
|
|
int width, height;
|
|
|
|
if (y1 < y2)
|
|
{
|
|
y_low = y1;
|
|
y_hi = y2;
|
|
}
|
|
else
|
|
{
|
|
y_low = y2;
|
|
y_hi = y1;
|
|
}
|
|
|
|
|
|
if (x1 < x2)
|
|
{
|
|
x_low = x1;
|
|
x_hi = x2;
|
|
}
|
|
else
|
|
{
|
|
x_low = x2;
|
|
x_hi = x1;
|
|
}
|
|
|
|
width = abs(x_hi - x_low) + 1;
|
|
height = abs(y_hi - y_low) + 1;
|
|
|
|
unsigned char *data = new unsigned char[ (width*height)*4 ];
|
|
this->GetRGBACharPixelData(x1, y1, x2, y2, front, data);
|
|
|
|
return data;
|
|
}
|
|
|
|
int vtkOpenGLRenderWindow::GetRGBACharPixelData(int x1, int y1,
|
|
int x2, int y2,
|
|
int front,
|
|
vtkUnsignedCharArray* data)
|
|
{
|
|
int y_low, y_hi;
|
|
int x_low, x_hi;
|
|
|
|
if (y1 < y2)
|
|
{
|
|
y_low = y1;
|
|
y_hi = y2;
|
|
}
|
|
else
|
|
{
|
|
y_low = y2;
|
|
y_hi = y1;
|
|
}
|
|
|
|
if (x1 < x2)
|
|
{
|
|
x_low = x1;
|
|
x_hi = x2;
|
|
}
|
|
else
|
|
{
|
|
x_low = x2;
|
|
x_hi = x1;
|
|
}
|
|
|
|
int width = abs(x_hi - x_low) + 1;
|
|
int height = abs(y_hi - y_low) + 1;
|
|
int size = 4*width*height;
|
|
|
|
if ( data->GetMaxId()+1 != size)
|
|
{
|
|
vtkDebugMacro("Resizing array.");
|
|
data->SetNumberOfComponents(4);
|
|
data->SetNumberOfValues(size);
|
|
}
|
|
return this->GetRGBACharPixelData(x1, y1, x2, y2, front,
|
|
data->GetPointer(0));
|
|
}
|
|
|
|
int vtkOpenGLRenderWindow::GetRGBACharPixelData(int x1, int y1,
|
|
int x2, int y2,
|
|
int front,
|
|
unsigned char* data)
|
|
{
|
|
int y_low, y_hi;
|
|
int x_low, x_hi;
|
|
int width, height;
|
|
|
|
|
|
// set the current window
|
|
this->MakeCurrent();
|
|
|
|
|
|
if (y1 < y2)
|
|
{
|
|
y_low = y1;
|
|
y_hi = y2;
|
|
}
|
|
else
|
|
{
|
|
y_low = y2;
|
|
y_hi = y1;
|
|
}
|
|
|
|
|
|
if (x1 < x2)
|
|
{
|
|
x_low = x1;
|
|
x_hi = x2;
|
|
}
|
|
else
|
|
{
|
|
x_low = x2;
|
|
x_hi = x1;
|
|
}
|
|
|
|
|
|
// Must clear previous errors first.
|
|
while(glGetError() != GL_NO_ERROR);
|
|
|
|
if (front)
|
|
{
|
|
glReadBuffer(GL_FRONT);
|
|
}
|
|
else
|
|
{
|
|
glReadBuffer(GL_BACK);
|
|
}
|
|
|
|
width = abs(x_hi - x_low) + 1;
|
|
height = abs(y_hi - y_low) + 1;
|
|
|
|
glDisable( GL_SCISSOR_TEST );
|
|
|
|
// Turn of texturing in case it is on - some drivers have a problem
|
|
// getting / setting pixels with texturing enabled.
|
|
glDisable( GL_TEXTURE_2D );
|
|
|
|
glReadPixels( x_low, y_low, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
|
|
data);
|
|
|
|
if (glGetError() != GL_NO_ERROR)
|
|
{
|
|
return VTK_ERROR;
|
|
}
|
|
else
|
|
{
|
|
return VTK_OK;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
int vtkOpenGLRenderWindow::SetRGBACharPixelData(int x1,int y1,int x2,int y2,
|
|
vtkUnsignedCharArray *data,
|
|
int front, int blend)
|
|
{
|
|
int y_low, y_hi;
|
|
int x_low, x_hi;
|
|
int width, height;
|
|
|
|
if (y1 < y2)
|
|
{
|
|
y_low = y1;
|
|
y_hi = y2;
|
|
}
|
|
else
|
|
{
|
|
y_low = y2;
|
|
y_hi = y1;
|
|
}
|
|
|
|
if (x1 < x2)
|
|
{
|
|
x_low = x1;
|
|
x_hi = x2;
|
|
}
|
|
else
|
|
{
|
|
x_low = x2;
|
|
x_hi = x1;
|
|
}
|
|
|
|
width = abs(x_hi-x_low) + 1;
|
|
height = abs(y_hi-y_low) + 1;
|
|
|
|
int size = 4*width*height;
|
|
if ( data->GetMaxId()+1 != size )
|
|
{
|
|
vtkErrorMacro("Buffer is of wrong size. It is " << data->GetMaxId()+1
|
|
<< ", it should be: " << size);
|
|
return VTK_ERROR;
|
|
}
|
|
|
|
return this->SetRGBACharPixelData(x1, y1, x2, y2, data->GetPointer(0),
|
|
front, blend);
|
|
|
|
}
|
|
|
|
int vtkOpenGLRenderWindow::SetRGBACharPixelData(int x1, int y1, int x2,
|
|
int y2, unsigned char *data,
|
|
int front, int blend)
|
|
{
|
|
int y_low, y_hi;
|
|
int x_low, x_hi;
|
|
int width, height;
|
|
|
|
|
|
// set the current window
|
|
this->MakeCurrent();
|
|
|
|
|
|
// Error checking
|
|
// Must clear previous errors first.
|
|
while(glGetError() != GL_NO_ERROR);
|
|
|
|
if (front)
|
|
{
|
|
glDrawBuffer(GL_FRONT);
|
|
}
|
|
else
|
|
{
|
|
glDrawBuffer(GL_BACK);
|
|
}
|
|
|
|
|
|
if (y1 < y2)
|
|
{
|
|
y_low = y1;
|
|
y_hi = y2;
|
|
}
|
|
else
|
|
{
|
|
y_low = y2;
|
|
y_hi = y1;
|
|
}
|
|
|
|
|
|
if (x1 < x2)
|
|
{
|
|
x_low = x1;
|
|
x_hi = x2;
|
|
}
|
|
else
|
|
{
|
|
x_low = x2;
|
|
x_hi = x1;
|
|
}
|
|
|
|
|
|
width = abs(x_hi-x_low) + 1;
|
|
height = abs(y_hi-y_low) + 1;
|
|
|
|
|
|
/* write out a row of pixels */
|
|
glMatrixMode( GL_MODELVIEW );
|
|
glPushMatrix();
|
|
glLoadIdentity();
|
|
glMatrixMode( GL_PROJECTION );
|
|
glPushMatrix();
|
|
glLoadIdentity();
|
|
glRasterPos3f( (2.0 * (GLfloat)(x_low) / this->Size[0] - 1),
|
|
(2.0 * (GLfloat)(y_low) / this->Size[1] - 1),
|
|
-1.0 );
|
|
glMatrixMode( GL_PROJECTION );
|
|
glPopMatrix();
|
|
glMatrixMode( GL_MODELVIEW );
|
|
glPopMatrix();
|
|
|
|
|
|
glDisable( GL_SCISSOR_TEST );
|
|
|
|
// Turn of texturing in case it is on - some drivers have a problem
|
|
// getting / setting pixels with texturing enabled.
|
|
glDisable( GL_TEXTURE_2D );
|
|
|
|
if (!blend)
|
|
{
|
|
glDisable(GL_BLEND);
|
|
glDrawPixels( width, height, GL_RGBA, GL_UNSIGNED_BYTE,
|
|
data);
|
|
glEnable(GL_BLEND);
|
|
}
|
|
else
|
|
{
|
|
glDrawPixels( width, height, GL_RGBA, GL_UNSIGNED_BYTE,
|
|
data);
|
|
}
|
|
|
|
// This seems to be necessary for the image to show up
|
|
glFlush();
|
|
|
|
if (glGetError() != GL_NO_ERROR)
|
|
{
|
|
return VTK_ERROR;
|
|
}
|
|
else
|
|
{
|
|
return VTK_OK;
|
|
}
|
|
}
|
|
|
|
|
|
int vtkOpenGLRenderWindow::GetZbufferData( int x1, int y1, int x2, int y2,
|
|
float* z_data )
|
|
{
|
|
int y_low;
|
|
int x_low;
|
|
int width, height;
|
|
|
|
// set the current window
|
|
this->MakeCurrent();
|
|
|
|
if (y1 < y2)
|
|
{
|
|
y_low = y1;
|
|
}
|
|
else
|
|
{
|
|
y_low = y2;
|
|
}
|
|
|
|
if (x1 < x2)
|
|
{
|
|
x_low = x1;
|
|
}
|
|
else
|
|
{
|
|
x_low = x2;
|
|
}
|
|
|
|
width = abs(x2 - x1)+1;
|
|
height = abs(y2 - y1)+1;
|
|
|
|
// Error checking
|
|
// Must clear previous errors first.
|
|
while(glGetError() != GL_NO_ERROR);
|
|
|
|
// Turn of texturing in case it is on - some drivers have a problem
|
|
// getting / setting pixels with texturing enabled.
|
|
glDisable( GL_TEXTURE_2D );
|
|
glDisable( GL_SCISSOR_TEST );
|
|
glPixelStorei( GL_PACK_ALIGNMENT, 1 );
|
|
|
|
glReadPixels( x_low, y_low,
|
|
width, height,
|
|
GL_DEPTH_COMPONENT, GL_FLOAT,
|
|
z_data );
|
|
|
|
if (glGetError() != GL_NO_ERROR)
|
|
{
|
|
return VTK_ERROR;
|
|
}
|
|
else
|
|
{
|
|
return VTK_OK;
|
|
}
|
|
}
|
|
|
|
float *vtkOpenGLRenderWindow::GetZbufferData( int x1, int y1, int x2, int y2 )
|
|
{
|
|
float *z_data;
|
|
|
|
int width, height;
|
|
width = abs(x2 - x1)+1;
|
|
height = abs(y2 - y1)+1;
|
|
|
|
z_data = new float[width*height];
|
|
this->GetZbufferData(x1, y1, x2, y2, z_data);
|
|
|
|
return z_data;
|
|
}
|
|
|
|
int vtkOpenGLRenderWindow::GetZbufferData( int x1, int y1, int x2, int y2,
|
|
vtkFloatArray *buffer )
|
|
{
|
|
int width, height;
|
|
width = abs(x2 - x1)+1;
|
|
height = abs(y2 - y1)+1;
|
|
int size = width*height;
|
|
if ( buffer->GetMaxId()+1 != size)
|
|
{
|
|
vtkDebugMacro("Resizing array.");
|
|
buffer->SetNumberOfComponents(1);
|
|
buffer->SetNumberOfValues(size);
|
|
}
|
|
return this->GetZbufferData(x1, y1, x2, y2, buffer->GetPointer(0));
|
|
}
|
|
|
|
int vtkOpenGLRenderWindow::SetZbufferData( int x1, int y1, int x2, int y2,
|
|
vtkFloatArray *buffer )
|
|
{
|
|
int width, height;
|
|
width = abs(x2 - x1)+1;
|
|
height = abs(y2 - y1)+1;
|
|
int size = width*height;
|
|
if ( buffer->GetMaxId()+1 != size )
|
|
{
|
|
vtkErrorMacro("Buffer is of wrong size.");
|
|
return VTK_ERROR;
|
|
}
|
|
return this->SetZbufferData(x1, y1, x2, y2, buffer->GetPointer(0));
|
|
}
|
|
|
|
int vtkOpenGLRenderWindow::SetZbufferData( int x1, int y1, int x2, int y2,
|
|
float *buffer )
|
|
{
|
|
int y_low;
|
|
int x_low;
|
|
int width, height;
|
|
|
|
// set the current window
|
|
this->MakeCurrent();
|
|
|
|
if (y1 < y2)
|
|
{
|
|
y_low = y1;
|
|
}
|
|
else
|
|
{
|
|
y_low = y2;
|
|
}
|
|
|
|
if (x1 < x2)
|
|
{
|
|
x_low = x1;
|
|
}
|
|
else
|
|
{
|
|
x_low = x2;
|
|
}
|
|
|
|
width = abs(x2 - x1)+1;
|
|
height = abs(y2 - y1)+1;
|
|
|
|
// Error checking
|
|
// Must clear previous errors first.
|
|
while(glGetError() != GL_NO_ERROR);
|
|
|
|
glMatrixMode( GL_MODELVIEW );
|
|
glPushMatrix();
|
|
glLoadIdentity();
|
|
glMatrixMode( GL_PROJECTION );
|
|
glPushMatrix();
|
|
glLoadIdentity();
|
|
glRasterPos2f( 2.0 * (GLfloat)(x_low) / this->Size[0] - 1,
|
|
2.0 * (GLfloat)(y_low) / this->Size[1] - 1);
|
|
glMatrixMode( GL_PROJECTION );
|
|
glPopMatrix();
|
|
glMatrixMode( GL_MODELVIEW );
|
|
glPopMatrix();
|
|
|
|
// Turn of texturing in case it is on - some drivers have a problem
|
|
// getting / setting pixels with texturing enabled.
|
|
glDisable( GL_SCISSOR_TEST );
|
|
glDisable( GL_TEXTURE_2D );
|
|
glPixelStorei( GL_PACK_ALIGNMENT, 1 );
|
|
|
|
glDrawPixels( width, height, GL_DEPTH_COMPONENT, GL_FLOAT, buffer);
|
|
|
|
// This seems to be necessary for the image to show up
|
|
glFlush();
|
|
|
|
if (glGetError() != GL_NO_ERROR)
|
|
{
|
|
return VTK_ERROR;
|
|
}
|
|
else
|
|
{
|
|
return VTK_OK;
|
|
}
|
|
}
|
|
|
|
|
|
void vtkOpenGLRenderWindow::RegisterTextureResource (GLuint id)
|
|
{
|
|
this->TextureResourceIds->InsertNextId ((int) id);
|
|
}
|
|
|
|
|
|
|