You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
565 lines
13 KiB
C++
565 lines
13 KiB
C++
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: vtkOSOpenGLRenderWindow.cxx
|
|
|
|
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 "vtkOSOpenGLRenderWindow.h"
|
|
#include "vtkOpenGLRenderer.h"
|
|
#include "vtkOpenGLProperty.h"
|
|
#include "vtkOpenGLTexture.h"
|
|
#include "vtkOpenGLCamera.h"
|
|
#include "vtkOpenGLLight.h"
|
|
#include "vtkOpenGLActor.h"
|
|
#include <GL/gl.h>
|
|
#include "vtkgl.h"
|
|
|
|
#ifdef VTK_USE_OSMESA
|
|
# include <GL/osmesa.h>
|
|
#endif
|
|
|
|
#include "vtkCommand.h"
|
|
#include "vtkIdList.h"
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkRendererCollection.h"
|
|
#include "vtkOpenGLExtensionManager.h"
|
|
|
|
#include "vtksys/SystemTools.hxx"
|
|
#include <sstream>
|
|
|
|
class vtkOSOpenGLRenderWindow;
|
|
class vtkRenderWindow;
|
|
|
|
class vtkOSOpenGLRenderWindowInternal
|
|
{
|
|
friend class vtkOSOpenGLRenderWindow;
|
|
private:
|
|
vtkOSOpenGLRenderWindowInternal(vtkRenderWindow*);
|
|
|
|
// store previous settings of on screen window
|
|
int ScreenDoubleBuffer;
|
|
int ScreenMapped;
|
|
|
|
// OffScreen stuff
|
|
OSMesaContext OffScreenContextId;
|
|
void *OffScreenWindow;
|
|
};
|
|
|
|
vtkOSOpenGLRenderWindowInternal::vtkOSOpenGLRenderWindowInternal(
|
|
vtkRenderWindow *rw)
|
|
{
|
|
|
|
this->ScreenMapped = rw->GetMapped();
|
|
this->ScreenDoubleBuffer = rw->GetDoubleBuffer();
|
|
|
|
// OpenGL specific
|
|
this->OffScreenContextId = NULL;
|
|
this->OffScreenWindow = NULL;
|
|
}
|
|
|
|
|
|
vtkStandardNewMacro(vtkOSOpenGLRenderWindow);
|
|
|
|
// a couple of routines for offscreen rendering
|
|
void vtkOSMesaDestroyWindow(void *Window)
|
|
{
|
|
free(Window);
|
|
}
|
|
|
|
void *vtkOSMesaCreateWindow(int width, int height)
|
|
{
|
|
return malloc(width*height*4);
|
|
}
|
|
|
|
vtkOSOpenGLRenderWindow::vtkOSOpenGLRenderWindow()
|
|
{
|
|
// this->ParentId = (Window)NULL;
|
|
this->ScreenSize[0] = 1280;
|
|
this->ScreenSize[1] = 1024;
|
|
this->OwnDisplay = 0;
|
|
this->CursorHidden = 0;
|
|
this->ForceMakeCurrent = 0;
|
|
this->OwnWindow = 0;
|
|
|
|
this->Internal = new vtkOSOpenGLRenderWindowInternal(this);
|
|
|
|
this->Capabilities = 0;
|
|
|
|
}
|
|
|
|
// free up memory & close the window
|
|
vtkOSOpenGLRenderWindow::~vtkOSOpenGLRenderWindow()
|
|
{
|
|
// close-down all system-specific drawing resources
|
|
this->Finalize();
|
|
|
|
vtkRenderer *ren;
|
|
vtkCollectionSimpleIterator rit;
|
|
this->Renderers->InitTraversal(rit);
|
|
while ( (ren = this->Renderers->GetNextRenderer(rit)) )
|
|
{
|
|
ren->SetRenderWindow(NULL);
|
|
}
|
|
|
|
delete this->Internal;
|
|
}
|
|
|
|
// End the rendering process and display the image.
|
|
void vtkOSOpenGLRenderWindow::Frame()
|
|
{
|
|
this->MakeCurrent();
|
|
glFlush();
|
|
}
|
|
|
|
//
|
|
// Set the variable that indicates that we want a stereo capable window
|
|
// be created. This method can only be called before a window is realized.
|
|
//
|
|
void vtkOSOpenGLRenderWindow::SetStereoCapableWindow(int capable)
|
|
{
|
|
if (!this->Internal->OffScreenContextId)
|
|
{
|
|
vtkOpenGLRenderWindow::SetStereoCapableWindow(capable);
|
|
}
|
|
else
|
|
{
|
|
vtkWarningMacro(<< "Requesting a StereoCapableWindow must be performed "
|
|
<< "before the window is realized, i.e. before a render.");
|
|
}
|
|
}
|
|
|
|
void vtkOSOpenGLRenderWindow::CreateAWindow()
|
|
{
|
|
this->CreateOffScreenWindow(this->ScreenSize[0], this->ScreenSize[1]);
|
|
}
|
|
|
|
void vtkOSOpenGLRenderWindow::DestroyWindow()
|
|
{
|
|
this->MakeCurrent();
|
|
|
|
// tell each of the renderers that this render window/graphics context
|
|
// is being removed (the RendererCollection is removed by vtkRenderWindow's
|
|
// destructor)
|
|
vtkRenderer* ren;
|
|
this->Renderers->InitTraversal();
|
|
for ( ren = vtkOpenGLRenderer::SafeDownCast(this->Renderers->GetNextItemAsObject());
|
|
ren != NULL;
|
|
ren = vtkOpenGLRenderer::SafeDownCast(this->Renderers->GetNextItemAsObject()) )
|
|
{
|
|
ren->SetRenderWindow(NULL);
|
|
ren->SetRenderWindow(this);
|
|
}
|
|
|
|
|
|
delete[] this->Capabilities;
|
|
this->Capabilities = 0;
|
|
|
|
this->DestroyOffScreenWindow();
|
|
|
|
// make sure all other code knows we're not mapped anymore
|
|
this->Mapped = 0;
|
|
|
|
}
|
|
|
|
void vtkOSOpenGLRenderWindow::CreateOffScreenWindow(int width, int height)
|
|
{
|
|
|
|
this->DoubleBuffer = 0;
|
|
|
|
if (!this->Internal->OffScreenWindow)
|
|
{
|
|
this->Internal->OffScreenWindow = vtkOSMesaCreateWindow(width,height);
|
|
this->OwnWindow = 1;
|
|
}
|
|
if (!this->Internal->OffScreenContextId)
|
|
{
|
|
this->Internal->OffScreenContextId = OSMesaCreateContext(GL_RGBA, NULL);
|
|
}
|
|
this->MakeCurrent();
|
|
|
|
this->Mapped = 0;
|
|
this->Size[0] = width;
|
|
this->Size[1] = height;
|
|
|
|
this->MakeCurrent();
|
|
|
|
// tell our renderers about us
|
|
vtkRenderer* ren;
|
|
for (this->Renderers->InitTraversal();
|
|
(ren = this->Renderers->GetNextItem());)
|
|
{
|
|
ren->SetRenderWindow(0);
|
|
ren->SetRenderWindow(this);
|
|
}
|
|
|
|
this->OpenGLInit();
|
|
}
|
|
|
|
void vtkOSOpenGLRenderWindow::DestroyOffScreenWindow()
|
|
{
|
|
|
|
// release graphic resources.
|
|
vtkRenderer *ren;
|
|
vtkCollectionSimpleIterator rit;
|
|
this->Renderers->InitTraversal(rit);
|
|
while ( (ren = this->Renderers->GetNextRenderer(rit)) )
|
|
{
|
|
ren->SetRenderWindow(NULL);
|
|
ren->SetRenderWindow(this);
|
|
}
|
|
|
|
|
|
if (this->Internal->OffScreenContextId)
|
|
{
|
|
OSMesaDestroyContext(this->Internal->OffScreenContextId);
|
|
this->Internal->OffScreenContextId = NULL;
|
|
vtkOSMesaDestroyWindow(this->Internal->OffScreenWindow);
|
|
this->Internal->OffScreenWindow = NULL;
|
|
}
|
|
}
|
|
|
|
void vtkOSOpenGLRenderWindow::ResizeOffScreenWindow(int width, int height)
|
|
{
|
|
if(this->Internal->OffScreenContextId)
|
|
{
|
|
this->DestroyOffScreenWindow();
|
|
this->CreateOffScreenWindow(width, height);
|
|
}
|
|
}
|
|
|
|
|
|
// Initialize the window for rendering.
|
|
void vtkOSOpenGLRenderWindow::WindowInitialize (void)
|
|
{
|
|
this->CreateAWindow();
|
|
|
|
this->MakeCurrent();
|
|
|
|
// tell our renderers about us
|
|
vtkRenderer* ren;
|
|
for (this->Renderers->InitTraversal();
|
|
(ren = this->Renderers->GetNextItem());)
|
|
{
|
|
ren->SetRenderWindow(0);
|
|
ren->SetRenderWindow(this);
|
|
}
|
|
|
|
this->OpenGLInit();
|
|
}
|
|
|
|
// Initialize the rendering window.
|
|
void vtkOSOpenGLRenderWindow::Initialize (void)
|
|
{
|
|
if(! (this->Internal->OffScreenContextId))
|
|
{
|
|
// initialize offscreen window
|
|
int width = ((this->Size[0] > 0) ? this->Size[0] : 300);
|
|
int height = ((this->Size[1] > 0) ? this->Size[1] : 300);
|
|
this->CreateOffScreenWindow(width, height);
|
|
}
|
|
}
|
|
|
|
void vtkOSOpenGLRenderWindow::Finalize (void)
|
|
{
|
|
|
|
// clean up offscreen stuff
|
|
this->SetOffScreenRendering(0);
|
|
|
|
// clean and destroy window
|
|
this->DestroyWindow();
|
|
|
|
}
|
|
|
|
// Change the window to fill the entire screen.
|
|
void vtkOSOpenGLRenderWindow::SetFullScreen(int arg)
|
|
{
|
|
(void)arg;
|
|
this->Modified();
|
|
}
|
|
|
|
// Resize the window.
|
|
void vtkOSOpenGLRenderWindow::WindowRemap()
|
|
{
|
|
// shut everything down
|
|
this->Finalize();
|
|
|
|
// set the default windowid
|
|
// this->WindowId = this->NextWindowId;
|
|
// this->NextWindowId = (Window)NULL;
|
|
|
|
// set everything up again
|
|
this->Initialize();
|
|
}
|
|
|
|
// Begin the rendering process.
|
|
void vtkOSOpenGLRenderWindow::Start(void)
|
|
{
|
|
this->Initialize();
|
|
|
|
// set the current window
|
|
this->MakeCurrent();
|
|
}
|
|
|
|
|
|
// Specify the size of the rendering window.
|
|
void vtkOSOpenGLRenderWindow::SetSize(int width,int height)
|
|
{
|
|
if ((this->Size[0] != width)||(this->Size[1] != height))
|
|
{
|
|
this->Superclass::SetSize(width, height);
|
|
this->ResizeOffScreenWindow(width, height);
|
|
this->Modified();
|
|
}
|
|
}
|
|
|
|
void vtkOSOpenGLRenderWindow::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os,indent);
|
|
|
|
os << indent << "OffScreenContextId: " << this->Internal->OffScreenContextId << "\n";
|
|
// os << indent << "Color Map: " << this->ColorMap << "\n";
|
|
// os << indent << "Next Window Id: " << this->NextWindowId << "\n";
|
|
// os << indent << "Window Id: " << this->GetWindowId() << "\n";
|
|
}
|
|
|
|
void vtkOSOpenGLRenderWindow::MakeCurrent()
|
|
{
|
|
// set the current window
|
|
if (this->Internal->OffScreenContextId)
|
|
{
|
|
if (OSMesaMakeCurrent(this->Internal->OffScreenContextId,
|
|
this->Internal->OffScreenWindow, GL_UNSIGNED_BYTE,
|
|
this->Size[0], this->Size[1]) != GL_TRUE)
|
|
{
|
|
vtkWarningMacro("failed call to OSMesaMakeCurrent");
|
|
}
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Description:
|
|
// Tells if this window is the current OpenGL context for the calling thread.
|
|
bool vtkOSOpenGLRenderWindow::IsCurrent()
|
|
{
|
|
bool result=false;
|
|
if(this->Internal->OffScreenContextId)
|
|
{
|
|
result=this->Internal->OffScreenContextId==OSMesaGetCurrentContext();
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
void vtkOSOpenGLRenderWindow::SetForceMakeCurrent()
|
|
{
|
|
this->ForceMakeCurrent = 1;
|
|
}
|
|
|
|
void *vtkOSOpenGLRenderWindow::GetGenericContext()
|
|
{
|
|
return (void *)this->Internal->OffScreenContextId;
|
|
}
|
|
|
|
int vtkOSOpenGLRenderWindow::GetEventPending()
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
// Get the size of the screen in pixels
|
|
int *vtkOSOpenGLRenderWindow::GetScreenSize()
|
|
{
|
|
|
|
this->ScreenSize[0] = 1280;
|
|
this->ScreenSize[1] = 1024;
|
|
return this->ScreenSize;
|
|
}
|
|
|
|
// Get the position in screen coordinates (pixels) of the window.
|
|
int *vtkOSOpenGLRenderWindow::GetPosition(void)
|
|
{
|
|
return this->Position;
|
|
}
|
|
|
|
// Move the window to a new position on the display.
|
|
void vtkOSOpenGLRenderWindow::SetPosition(int x, int y)
|
|
{
|
|
if ((this->Position[0] != x)||(this->Position[1] != y))
|
|
{
|
|
this->Modified();
|
|
}
|
|
this->Position[0] = x;
|
|
this->Position[1] = y;
|
|
}
|
|
|
|
// Set this RenderWindow's X window id to a pre-existing window.
|
|
void vtkOSOpenGLRenderWindow::SetWindowInfo(char *info)
|
|
{
|
|
int tmp;
|
|
|
|
this->OwnDisplay = 1;
|
|
|
|
sscanf(info,"%i",&tmp);
|
|
|
|
}
|
|
|
|
// Set this RenderWindow's X window id to a pre-existing window.
|
|
void vtkOSOpenGLRenderWindow::SetNextWindowInfo(char *info)
|
|
{
|
|
int tmp;
|
|
sscanf(info,"%i",&tmp);
|
|
|
|
// this->SetNextWindowId((Window)tmp);
|
|
}
|
|
|
|
// Sets the X window id of the window that WILL BE created.
|
|
void vtkOSOpenGLRenderWindow::SetParentInfo(char *info)
|
|
{
|
|
int tmp;
|
|
|
|
// get the default display connection
|
|
this->OwnDisplay = 1;
|
|
|
|
sscanf(info,"%i",&tmp);
|
|
|
|
// this->SetParentId(tmp);
|
|
}
|
|
|
|
void vtkOSOpenGLRenderWindow::SetWindowId(void *arg)
|
|
{
|
|
(void)arg;
|
|
// this->SetWindowId((Window)arg);
|
|
}
|
|
void vtkOSOpenGLRenderWindow::SetParentId(void *arg)
|
|
{
|
|
(void)arg;
|
|
// this->SetParentId((Window)arg);
|
|
}
|
|
|
|
const char* vtkOSOpenGLRenderWindow::ReportCapabilities()
|
|
{
|
|
MakeCurrent();
|
|
|
|
// int scrnum = DefaultScreen(this->DisplayId);
|
|
|
|
const char *glVendor = (const char *) glGetString(GL_VENDOR);
|
|
const char *glRenderer = (const char *) glGetString(GL_RENDERER);
|
|
const char *glVersion = (const char *) glGetString(GL_VERSION);
|
|
const char *glExtensions = (const char *) glGetString(GL_EXTENSIONS);
|
|
|
|
std::ostringstream strm;
|
|
strm << "OpenGL vendor string: " << glVendor << endl;
|
|
strm << "OpenGL renderer string: " << glRenderer << endl;
|
|
strm << "OpenGL version string: " << glVersion << endl;
|
|
strm << "OpenGL extensions: " << glExtensions << endl;
|
|
delete[] this->Capabilities;
|
|
size_t len = strm.str().length();
|
|
this->Capabilities = new char[len + 1];
|
|
strncpy(this->Capabilities, strm.str().c_str(), len);
|
|
this->Capabilities[len] = 0;
|
|
return this->Capabilities;
|
|
}
|
|
|
|
int vtkOSOpenGLRenderWindow::SupportsOpenGL()
|
|
{
|
|
MakeCurrent();
|
|
return 1;
|
|
}
|
|
|
|
|
|
int vtkOSOpenGLRenderWindow::IsDirect()
|
|
{
|
|
MakeCurrent();
|
|
return 0;
|
|
}
|
|
|
|
|
|
void vtkOSOpenGLRenderWindow::SetWindowName(const char * cname)
|
|
{
|
|
char *name = new char[ strlen(cname)+1 ];
|
|
strcpy(name, cname);
|
|
vtkOpenGLRenderWindow::SetWindowName( name );
|
|
delete [] name;
|
|
}
|
|
|
|
// Specify the X window id to use if a WindowRemap is done.
|
|
/*void vtkOSOpenGLRenderWindow::SetNextWindowId(Window arg)
|
|
{
|
|
vtkDebugMacro(<< "Setting NextWindowId to " << (void *)arg << "\n");
|
|
|
|
this->NextWindowId = arg;
|
|
}*/
|
|
|
|
void vtkOSOpenGLRenderWindow::SetNextWindowId(void *arg)
|
|
{
|
|
(void)arg;
|
|
// this->SetNextWindowId((Window)arg);
|
|
}
|
|
|
|
|
|
// Set the X display id for this RenderWindow to use to a pre-existing
|
|
// X display id.
|
|
/*void vtkOSOpenGLRenderWindow::SetDisplayId(Display *arg)
|
|
{
|
|
vtkDebugMacro(<< "Setting DisplayId to " << (void *)arg << "\n");
|
|
|
|
this->DisplayId = arg;
|
|
this->OwnDisplay = 0;
|
|
|
|
}*/
|
|
|
|
/*void vtkOSOpenGLRenderWindow::SetDisplayId(void *arg)
|
|
{
|
|
this->SetDisplayId((Display *)arg);
|
|
this->OwnDisplay = 0;
|
|
}*/
|
|
|
|
//============================================================================
|
|
// Stuff above this is almost a mirror of vtkOSOpenGLRenderWindow.
|
|
// The code specific to OpenGL Off-Screen stuff may eventually be
|
|
// put in a supper class so this whole file could just be included
|
|
// (mangled) from vtkOSOpenGLRenderWindow like the other OpenGL classes.
|
|
//============================================================================
|
|
|
|
void vtkOSOpenGLRenderWindow::SetOffScreenRendering(int i)
|
|
{
|
|
if (this->OffScreenRendering == i)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// invoke super
|
|
this->vtkRenderWindow::SetOffScreenRendering(i);
|
|
|
|
this->Internal->ScreenDoubleBuffer = this->DoubleBuffer;
|
|
this->DoubleBuffer = 0;
|
|
if(this->Mapped)
|
|
{
|
|
this->DestroyWindow();
|
|
}
|
|
|
|
// delay initialization until Render
|
|
}
|
|
|
|
// This probably has been moved to superclass.
|
|
void *vtkOSOpenGLRenderWindow::GetGenericWindowId()
|
|
{
|
|
return (void *)this->Internal->OffScreenWindow;
|
|
}
|
|
|
|
void vtkOSOpenGLRenderWindow::SetCurrentCursor(int shape)
|
|
{
|
|
if ( this->InvokeEvent(vtkCommand::CursorChangedEvent,&shape) )
|
|
{
|
|
return;
|
|
}
|
|
this->Superclass::SetCurrentCursor(shape);
|
|
}
|