Cloned library of VTK-5.0.0 with extra build files for internal package management.
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.

335 lines
8.2 KiB

2 years ago
/*=========================================================================
Program: Visualization Toolkit
Module: $RCSfile: vtkOpenGLRenderer.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 "vtkOpenGLRenderer.h"
#include "vtkCuller.h"
#include "vtkLightCollection.h"
#include "vtkObjectFactory.h"
#include "vtkOpenGLCamera.h"
#include "vtkOpenGLLight.h"
#include "vtkOpenGLProperty.h"
#include "vtkRenderWindow.h"
#ifndef VTK_IMPLEMENT_MESA_CXX
# include "vtkOpenGL.h"
#endif
#include <math.h>
class vtkGLPickInfo
{
public:
GLuint* PickBuffer;
GLuint PickedId;
};
#ifndef VTK_IMPLEMENT_MESA_CXX
vtkCxxRevisionMacro(vtkOpenGLRenderer, "$Revision: 1.50 $");
vtkStandardNewMacro(vtkOpenGLRenderer);
#endif
#define VTK_MAX_LIGHTS 8
vtkOpenGLRenderer::vtkOpenGLRenderer()
{
this->PickInfo = new vtkGLPickInfo;
this->NumberOfLightsBound = 0;
this->PickInfo->PickBuffer = 0;
this->PickInfo->PickedId = 0;
this->PickedZ = 0;
}
// Internal method temporarily removes lights before reloading them
// into graphics pipeline.
void vtkOpenGLRenderer::ClearLights (void)
{
short curLight;
float Info[4];
// define a lighting model and set up the ambient light.
// use index 11 for the heck of it. Doesn't matter except for 0.
// update the ambient light
Info[0] = this->Ambient[0];
Info[1] = this->Ambient[1];
Info[2] = this->Ambient[2];
Info[3] = 1.0;
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, Info);
if ( this->TwoSidedLighting )
{
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
}
else
{
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
}
// now delete all the old lights
for (curLight = GL_LIGHT0; curLight < GL_LIGHT0 + VTK_MAX_LIGHTS; curLight++)
{
glDisable((GLenum)curLight);
}
this->NumberOfLightsBound = 0;
}
// Ask lights to load themselves into graphics pipeline.
int vtkOpenGLRenderer::UpdateLights ()
{
vtkLight *light;
short curLight;
float status;
int count;
// Check if a light is on. If not then make a new light.
count = 0;
curLight= this->NumberOfLightsBound + GL_LIGHT0;
vtkCollectionSimpleIterator sit;
for(this->Lights->InitTraversal(sit);
(light = this->Lights->GetNextLight(sit)); )
{
status = light->GetSwitch();
if ((status > 0.0)&& (curLight < (GL_LIGHT0+VTK_MAX_LIGHTS)))
{
curLight++;
count++;
}
}
if( !count )
{
vtkDebugMacro(<<"No lights are on, creating one.");
this->CreateLight();
}
count = 0;
curLight= this->NumberOfLightsBound + GL_LIGHT0;
// set the matrix mode for lighting. ident matrix on viewing stack
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
for(this->Lights->InitTraversal(sit);
(light = this->Lights->GetNextLight(sit)); )
{
status = light->GetSwitch();
// if the light is on then define it and bind it.
// also make sure we still have room.
if ((status > 0.0)&& (curLight < (GL_LIGHT0+VTK_MAX_LIGHTS)))
{
light->Render((vtkRenderer *)this,curLight);
glEnable((GLenum)curLight);
// increment the current light by one
curLight++;
count++;
}
}
this->NumberOfLightsBound = curLight - GL_LIGHT0;
glPopMatrix();
glEnable(GL_LIGHTING);
return count;
}
// Concrete open gl render method.
void vtkOpenGLRenderer::DeviceRender(void)
{
// Do not remove this MakeCurrent! Due to Start / End methods on
// some objects which get executed during a pipeline update,
// other windows might get rendered since the last time
// a MakeCurrent was called.
this->RenderWindow->MakeCurrent();
// standard render method
this->ClearLights();
this->UpdateCamera();
this->UpdateLightGeometry();
this->UpdateLights();
// set matrix mode for actors
glMatrixMode(GL_MODELVIEW);
this->UpdateGeometry();
// clean up the model view matrix set up by the camera
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
void vtkOpenGLRenderer::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
os << indent << "Number Of Lights Bound: " <<
this->NumberOfLightsBound << "\n";
os << indent << "PickBuffer " << this->PickInfo->PickBuffer << "\n";
os << indent << "PickedId" << this->PickInfo->PickedId<< "\n";
os << indent << "PickedZ " << this->PickedZ << "\n";
}
void vtkOpenGLRenderer::Clear(void)
{
GLbitfield clear_mask = 0;
if (! this->Transparent())
{
glClearColor( ((GLclampf)(this->Background[0])),
((GLclampf)(this->Background[1])),
((GLclampf)(this->Background[2])),
((GLclampf)(0.0)) );
clear_mask |= GL_COLOR_BUFFER_BIT;
}
glClearDepth( (GLclampd)( 1.0 ) );
clear_mask |= GL_DEPTH_BUFFER_BIT;
vtkDebugMacro(<< "glClear\n");
glClear(clear_mask);
}
void vtkOpenGLRenderer::StartPick(unsigned int pickFromSize)
{
int bufferSize = pickFromSize * 4;
// Do not remove this MakeCurrent! Due to Start / End methods on
// some objects which get executed during a pipeline update,
// other windows might get rendered since the last time
// a MakeCurrent was called.
this->RenderWindow->MakeCurrent();
this->RenderWindow->IsPickingOn();
this->PickInfo->PickBuffer = new GLuint[bufferSize];
glSelectBuffer(bufferSize, this->PickInfo->PickBuffer);
// change to selection mode
(void)glRenderMode(GL_SELECT);
// initialize the pick names and add a 0 name, for no pick
glInitNames();
glPushName(0);
}
void vtkOpenGLRenderer::UpdatePickId()
{
glLoadName(this->CurrentPickId++);
}
void vtkOpenGLRenderer::DevicePickRender()
{
// Do not remove this MakeCurrent! Due to Start / End methods on
// some objects which get executed during a pipeline update,
// other windows might get rendered since the last time
// a MakeCurrent was called.
this->RenderWindow->MakeCurrent();
// standard render method
this->ClearLights();
this->UpdateCamera();
this->UpdateLightGeometry();
this->UpdateLights();
// set matrix mode for actors
glMatrixMode(GL_MODELVIEW);
this->PickGeometry();
// clean up the model view matrix set up by the camera
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
void vtkOpenGLRenderer::DonePick()
{
glFlush();
GLuint hits = glRenderMode(GL_RENDER);
unsigned int depth = (unsigned int)-1;
GLuint* ptr = this->PickInfo->PickBuffer;
this->PickInfo->PickedId = 0;
for(unsigned int k =0; k < hits; k++)
{
int num_names = *ptr;
int save = 0;
ptr++; // move to first depth value
if(*ptr <= depth)
{
depth = *ptr;
save = 1;
}
ptr++; // move to next depth value
if(*ptr <= depth)
{
depth = *ptr;
save = 1;
}
// move to first name picked
ptr++;
if(save)
{
this->PickInfo->PickedId = *ptr;
}
// skip additonal names
ptr += num_names;
}
// If there was a pick, then get the Z value
if(this->PickInfo->PickedId)
{
// convert from pick depth described as:
// Returned depth values are mapped such that the largest unsigned
// integer value corresponds to window coordinate depth 1.0,
// and zero corresponds to window coordinate depth 0.0.
this->PickedZ = ((double)depth / (double)VTK_UNSIGNED_INT_MAX);
// Clamp to range [0,1]
this->PickedZ = (this->PickedZ < 0.0) ? 0.0 : this->PickedZ;
this->PickedZ = (this->PickedZ > 1.0) ? 1.0: this->PickedZ;
}
delete [] this->PickInfo->PickBuffer;
this->PickInfo->PickBuffer = 0;
this->RenderWindow->IsPickingOff();
}
double vtkOpenGLRenderer::GetPickedZ()
{
return this->PickedZ;
}
unsigned int vtkOpenGLRenderer::GetPickedId()
{
return (unsigned int)this->PickInfo->PickedId;
}
vtkOpenGLRenderer::~vtkOpenGLRenderer()
{
if (this->PickInfo->PickBuffer)
{
delete [] this->PickInfo->PickBuffer;
this->PickInfo->PickBuffer = 0;
}
delete this->PickInfo;
}