mirror of https://gitee.com/openkylin/vtk9.git
201 lines
6.3 KiB
C++
201 lines
6.3 KiB
C++
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: vtkOpenGLContextBufferId.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 "vtkOpenGLContextBufferId.h"
|
|
|
|
#include "vtkIntArray.h"
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkOpenGLError.h"
|
|
#include "vtkOpenGLRenderWindow.h"
|
|
#include "vtkOpenGLState.h"
|
|
#include "vtkOpenGLTexture.h"
|
|
#include "vtkTextureObject.h"
|
|
#include <cassert>
|
|
|
|
vtkStandardNewMacro(vtkOpenGLContextBufferId);
|
|
|
|
//------------------------------------------------------------------------------
|
|
vtkOpenGLContextBufferId::vtkOpenGLContextBufferId()
|
|
{
|
|
this->Texture = nullptr;
|
|
this->Context = nullptr;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
vtkOpenGLContextBufferId::~vtkOpenGLContextBufferId()
|
|
{
|
|
if (this->Texture != nullptr)
|
|
{
|
|
vtkErrorMacro("texture should have been released.");
|
|
}
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
void vtkOpenGLContextBufferId::ReleaseGraphicsResources()
|
|
{
|
|
if (this->Texture != nullptr)
|
|
{
|
|
this->Texture->Delete();
|
|
this->Texture = nullptr;
|
|
}
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
void vtkOpenGLContextBufferId::SetContext(vtkRenderWindow* context)
|
|
{
|
|
vtkOpenGLRenderWindow* c = vtkOpenGLRenderWindow::SafeDownCast(context);
|
|
if (this->Context != c)
|
|
{
|
|
this->ReleaseGraphicsResources();
|
|
this->Context = c;
|
|
this->Modified();
|
|
}
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
vtkRenderWindow* vtkOpenGLContextBufferId::GetContext()
|
|
{
|
|
return this->Context;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
bool vtkOpenGLContextBufferId::IsSupported()
|
|
{
|
|
assert("pre: context_is_set" && this->GetContext() != nullptr);
|
|
return vtkTextureObject::IsSupported(this->Context);
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
void vtkOpenGLContextBufferId::Allocate()
|
|
{
|
|
assert("pre: positive_width" && this->GetWidth() > 0);
|
|
assert("pre: positive_height" && this->GetHeight() > 0);
|
|
assert("pre: context_is_set" && this->GetContext() != nullptr);
|
|
|
|
if (this->Texture == nullptr)
|
|
{
|
|
this->Texture = vtkTextureObject::New();
|
|
this->Texture->SetContext(this->Context);
|
|
}
|
|
this->Context->MakeCurrent();
|
|
// 3: RGB
|
|
this->Texture->Allocate2D(static_cast<unsigned int>(this->GetWidth()),
|
|
static_cast<unsigned int>(this->GetHeight()), 3, VTK_UNSIGNED_CHAR);
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
bool vtkOpenGLContextBufferId::IsAllocated() const
|
|
{
|
|
return this->Texture != nullptr &&
|
|
this->Texture->GetWidth() == static_cast<unsigned int>(this->Width) &&
|
|
this->Texture->GetHeight() == static_cast<unsigned int>(this->Height);
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
void vtkOpenGLContextBufferId::SetValues(int srcXmin, int srcYmin)
|
|
{
|
|
assert("pre: is_allocated" && this->IsAllocated());
|
|
|
|
// copy the current read buffer to the texture.
|
|
this->Texture->CopyFromFrameBuffer(srcXmin, srcYmin, 0, 0, this->Width, this->Height);
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
vtkIdType vtkOpenGLContextBufferId::GetPickedItem(int x, int y)
|
|
{
|
|
assert("pre: is_allocated" && this->IsAllocated());
|
|
|
|
vtkOpenGLClearErrorMacro();
|
|
|
|
vtkIdType result = -1;
|
|
if (x < 0 || x >= this->Width)
|
|
{
|
|
vtkDebugMacro(<< "x mouse position out of range: x=" << x << " (width=" << this->Width << ")");
|
|
}
|
|
else
|
|
{
|
|
if (y < 0 || y >= this->Height)
|
|
{
|
|
vtkDebugMacro(<< "y mouse position out of range: y=" << y << " (height=" << this->Height
|
|
<< ")");
|
|
}
|
|
else
|
|
{
|
|
this->Context->MakeCurrent();
|
|
vtkOpenGLState* ostate = this->Context->GetState();
|
|
|
|
// Render texture to current write buffer. Texel x,y is rendered at
|
|
// pixel x,y (instead of pixel 0,0 to work around pixel ownership test).
|
|
GLint savedDrawBuffer;
|
|
glGetIntegerv(GL_DRAW_BUFFER, &savedDrawBuffer);
|
|
|
|
vtkOpenGLState::ScopedglEnableDisable dsaver(ostate, GL_DEPTH_TEST);
|
|
vtkOpenGLState::ScopedglEnableDisable ssaver(ostate, GL_STENCIL_TEST);
|
|
vtkOpenGLState::ScopedglEnableDisable bsaver(ostate, GL_BLEND);
|
|
|
|
if (savedDrawBuffer != GL_BACK_LEFT)
|
|
{
|
|
ostate->vtkglDrawBuffer(GL_BACK_LEFT);
|
|
}
|
|
ostate->vtkglDisable(GL_DEPTH_TEST);
|
|
ostate->vtkglDisable(GL_STENCIL_TEST);
|
|
ostate->vtkglDisable(GL_BLEND);
|
|
|
|
this->Texture->CopyToFrameBuffer(x, y, x, y, x, y, this->Context->GetSize()[0],
|
|
this->Context->GetSize()[1], nullptr, nullptr);
|
|
|
|
GLint savedReadBuffer;
|
|
glGetIntegerv(GL_READ_BUFFER, &savedReadBuffer);
|
|
ostate->vtkglReadBuffer(GL_BACK_LEFT);
|
|
|
|
// To workaround pixel ownership test,
|
|
// get value from current read buffer at pixel (x,y) instead of just
|
|
// (0,0).
|
|
ostate->vtkglPixelStorei(GL_PACK_ALIGNMENT, 1);
|
|
unsigned char rgb[3];
|
|
rgb[0] = 5;
|
|
rgb[1] = 1;
|
|
rgb[2] = 8;
|
|
glReadPixels(x, y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, rgb);
|
|
|
|
if (savedReadBuffer != GL_BACK_LEFT)
|
|
{
|
|
ostate->vtkglReadBuffer(static_cast<GLenum>(savedReadBuffer));
|
|
}
|
|
if (savedDrawBuffer != GL_BACK_LEFT)
|
|
{
|
|
ostate->vtkglDrawBuffer(static_cast<GLenum>(savedDrawBuffer));
|
|
}
|
|
|
|
int value = (static_cast<int>(rgb[0]) << 16) | (static_cast<int>(rgb[1]) << 8) |
|
|
static_cast<int>(rgb[2]);
|
|
|
|
result = static_cast<vtkIdType>(value - 1);
|
|
}
|
|
}
|
|
|
|
assert("post: valid_result" && result >= -1);
|
|
|
|
vtkOpenGLCheckErrorMacro("failed after GetPickedItem");
|
|
|
|
return result;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
void vtkOpenGLContextBufferId::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os, indent);
|
|
}
|