Commit a9c4a043 authored by Marcus D. Hanwell's avatar Marcus D. Hanwell

Implement a basic VBO based poly data mapper

This makes use of the code developed for the scene, but ports it to
a more direct use of VBOs in the derived poly data mapper.

Change-Id: Idb0db244abbb0e6857818589b20aae22e10abd53
parent 3c6d2972
find_package(OpenGL REQUIRED)
find_package(GLEW REQUIRED)
find_package(Eigen3 REQUIRED)
include_directories(SYSTEM
${OPENGL_INCLUDE_DIR}
${GLEW_INCLUDE_DIRS})
${GLEW_INCLUDE_DIRS}
${EIGEN3_INCLUDE_DIR})
if(WIN32 AND NOT BUILD_SHARED_LIBS)
add_definitions(-DGLEW_STATIC)
endif()
......@@ -12,9 +14,37 @@ set(${vtk-module}_SYSTEM_INCLUDE_DIRS
${GLEW_INCLUDE_DIRS})
set(Module_SRCS
vtkglBufferObject.cxx
vtkglShader.cxx
vtkglShaderProgram.cxx
vtkglTexture2D.cxx
vtkVBOPolyDataMapper.cxx
${CMAKE_CURRENT_BINARY_DIR}/${vtk-module}ObjectFactory.cxx
)
set(shader_files
glsl/mesh_vs.glsl
glsl/mesh_fs.glsl
)
unset(shader_h_files)
foreach(file ${shader_files})
get_filename_component(file_we ${file} NAME_WE)
set(src ${CMAKE_CURRENT_SOURCE_DIR}/${file})
set(res ${CMAKE_CURRENT_BINARY_DIR}/${file_we}.cxx)
set(resh ${CMAKE_CURRENT_BINARY_DIR}/${file_we}.h)
list(APPEND shader_h_files ${resh})
add_custom_command(
OUTPUT ${res} ${resh}
DEPENDS ${src} vtkEncodeString
COMMAND vtkEncodeString
ARGS ${res} ${src} ${file_we}
--build-header VTKRENDERINGOPENGL2_EXPORT vtkRenderingOpenGL2Module.h
)
list(APPEND Module_SRCS ${res})
set_source_files_properties(${file_we} WRAP_EXCLUDE)
endforeach()
if(VTK_USE_X)
find_package(X11 REQUIRED)
if(NOT X11_Xt_FOUND)
......
vtk_add_test_cxx(
TestRenderWidget.cxx
TestVBOPLYMapper.cxx
)
vtk_test_cxx_executable(${vtk-module}CxxTests)
vtk_test_cxx_executable(${vtk-module}CxxTests RENDERING_FACTORY)
/*=========================================================================
Program: Visualization Toolkit
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 "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkActor.h"
#include "vtkCellArray.h"
#include "vtkPointData.h"
#include "vtkPolyDataNormals.h"
#include "vtkVBOPolyDataMapper.h"
#include "vtkPLYReader.h"
#include "vtkNew.h"
#include "vtkTimerLog.h"
#include "vtkRegressionTestImage.h"
#include "vtkTestUtilities.h"
//----------------------------------------------------------------------------
int TestVBOPLYMapper(int argc, char *argv[])
{
vtkNew<vtkActor> actor;
vtkNew<vtkVBOPolyDataMapper> mapper;
vtkNew<vtkRenderer> renderer;
renderer->SetBackground(0.0, 0.0, 0.0);
vtkNew<vtkRenderWindow> renderWindow;
renderWindow->SetSize(300, 300);
renderWindow->AddRenderer(renderer.Get());
renderer->AddActor(actor.Get());
const char* fileName = vtkTestUtilities::ExpandDataFileName(argc, argv,
"Data/dragon.ply");
vtkNew<vtkPLYReader> reader;
reader->SetFileName(fileName);
reader->Update();
vtkNew<vtkPolyDataNormals> computeNormals;
computeNormals->SetInputConnection(reader->GetOutputPort());
computeNormals->Update();
mapper->SetInputConnection(computeNormals->GetOutputPort());
actor->SetMapper(mapper.Get());
vtkNew<vtkRenderWindowInteractor> interactor;
interactor->SetRenderWindow(renderWindow.Get());
renderWindow->SetMultiSamples(0);
interactor->Initialize();
vtkNew<vtkTimerLog> timer;
double time(0.0);
for (int i = 0; i < 10; ++i)
{
timer->StartTimer();
renderWindow->Render();
timer->StopTimer();
cout << "Rendering frame " << i << ": " << timer->GetElapsedTime() << endl;
time += timer->GetElapsedTime();
}
cout << "Average time: " << time / 10.0 << endl;
interactor->Start();
delete [] fileName;
return EXIT_SUCCESS;
}
varying vec3 fnormal;
void main()
{
vec3 N = normalize(fnormal);
vec3 L = normalize(vec3(0, 1, 1));
vec3 E = vec3(0, 0, 1);
vec3 H = normalize(L + E);
float df = max(0.0, dot(N, L));
float sf = max(0.0, dot(N, H));
vec4 ambient = 0.4 * gl_Color;
vec4 diffuse = 0.55 * gl_Color;
vec4 specular = 0.5 * (vec4(1, 1, 1, 1) - gl_Color);
gl_FragColor = ambient + df * diffuse + pow(sf, 20.0) * specular;
gl_FragColor.a = gl_Color.a;
}
attribute vec4 vertex;
attribute vec3 normal;
uniform vec3 color;
uniform mat4 modelView;
uniform mat4 projection;
uniform mat3 normalMatrix;
varying vec3 fnormal;
void main()
{
gl_FrontColor = vec4(color, 1.0);
gl_Position = projection * modelView * vertex;
fnormal = normalize(normalMatrix * normal);
}
......@@ -12,5 +12,6 @@ vtk_module(vtkRenderingOpenGL2
vtkTestingRendering
vtkInteractionStyle
vtkIOPLY
vtkRenderingOpenGL
EXCLUDE_FROM_WRAPPING
)
This diff is collapsed.
/*=========================================================================
Program: Visualization Toolkit
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.
=========================================================================*/
// .NAME vtkVBOPolyDataMapper - PolyDataMapper using VBOs primarily to render.
// .SECTION Description
// PolyDataMapper that uses a VBOs to do the actual rendering.
#ifndef __vtkVBOPolyDataMapper_h
#define __vtkVBOPolyDataMapper_h
#include "vtkRenderingOpenGL2Module.h" // For export macro
#include "vtkPolyDataMapper.h"
class VTKRENDERINGOPENGL2_EXPORT vtkVBOPolyDataMapper : public vtkPolyDataMapper
{
public:
static vtkVBOPolyDataMapper* New();
vtkTypeMacro(vtkVBOPolyDataMapper, vtkPolyDataMapper)
void PrintSelf(ostream& os, vtkIndent indent);
// Description:
// Implemented by sub classes. Actual rendering is done here.
virtual void RenderPiece(vtkRenderer *ren, vtkActor *act);
// Description:
// Release any graphics resources that are being consumed by this mapper.
// The parameter window could be used to determine which graphic
// resources to release. Merely propagates the call to the painter.
void ReleaseGraphicsResources(vtkWindow *);
// Description:
// WARNING: INTERNAL METHOD - NOT INTENDED FOR GENERAL USE
// DO NOT USE THIS METHOD OUTSIDE OF THE RENDERING PROCESS
// Used by vtkHardwareSelector to determine if the prop supports hardware
// selection.
virtual bool GetSupportsSelection() { return false; }
// Description:
// Returns if the mapper does not expect to have translucent geometry. This
// may happen when using ScalarMode is set to not map scalars i.e. render the
// scalar array directly as colors and the scalar array has opacity i.e. alpha
// component. Note that even if this method returns true, an actor may treat
// the geometry as translucent since a constant translucency is set on the
// property, for example.
// Overridden to use the actual data and ScalarMode to determine if we have
// opaque geometry.
virtual bool GetIsOpaque();
protected:
vtkVBOPolyDataMapper();
~vtkVBOPolyDataMapper();
// Description:
// Called in GetBounds(). When this method is called, the consider the input
// to be updated depending on whether this->Static is set or not. This method
// simply obtains the bounds from the data-object and returns it.
virtual void ComputeBounds();
// Description:
// Update the scene when necessary.
void UpdateVBO();
// Description:
// The scene used by the mapper, all rendering is deferred to the scene.
class Private;
Private *Internal;
vtkTimeStamp VBOUpdateTime; // When was the VBO updated?
bool Initialized; // Hack - ensure glewinit has been called - move to window.
private:
vtkVBOPolyDataMapper(const vtkVBOPolyDataMapper&); // Not implemented.
void operator=(const vtkVBOPolyDataMapper&); // Not implemented.
};
#endif
/*=========================================================================
Program: Visualization Toolkit
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 "vtkglBufferObject.h"
#include <GL/glew.h>
namespace vtkgl {
namespace {
inline GLenum convertType(BufferObject::ObjectType type)
{
switch (type) {
default:
case BufferObject::ArrayBuffer:
return GL_ARRAY_BUFFER;
case BufferObject::ElementArrayBuffer:
return GL_ELEMENT_ARRAY_BUFFER;
}
}
}
struct BufferObject::Private
{
Private() : handle(0) {}
GLenum type;
GLuint handle;
};
BufferObject::BufferObject(ObjectType type_)
: d(new Private), m_dirty(true)
{
if (type_ == ArrayBuffer)
d->type = GL_ARRAY_BUFFER;
else
d->type = GL_ELEMENT_ARRAY_BUFFER;
}
BufferObject::~BufferObject()
{
if (d->handle != 0)
glDeleteBuffers(1, &d->handle);
delete d;
}
BufferObject::ObjectType BufferObject::type() const
{
if (d->type == GL_ARRAY_BUFFER)
return ArrayBuffer;
else
return ElementArrayBuffer;
}
int BufferObject::handle() const
{
return static_cast<int>(d->handle);
}
bool BufferObject::bind()
{
if (!d->handle)
return false;
glBindBuffer(d->type, d->handle);
return true;
}
bool BufferObject::release()
{
if (!d->handle)
return false;
glBindBuffer(d->type, 0);
return true;
}
bool BufferObject::uploadInternal(const void *buffer, size_t size,
ObjectType objectType)
{
GLenum objectTypeGl = convertType(objectType);
if (d->handle == 0) {
glGenBuffers(1, &d->handle);
d->type = objectTypeGl;
}
else if (d->type != objectTypeGl) {
m_error = "Trying to upload array buffer to incompatible buffer.";
return false;
}
glBindBuffer(d->type, d->handle);
glBufferData(d->type, size, static_cast<const GLvoid *>(buffer),
GL_STATIC_DRAW);
m_dirty = false;
return true;
}
}
/*=========================================================================
Program: Visualization Toolkit
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.
=========================================================================*/
#ifndef __vtkglBufferObject_h
#define __vtkglBufferObject_h
#include "vtkRenderingOpenGL2Module.h"
#include <string> // For member variables.
namespace vtkgl {
/**
* @brief OpenGL buffer object
*
* OpenGL buffer object to store geometry/attribute data on the GPU.
*/
class VTKRENDERINGOPENGL2_EXPORT BufferObject
{
public:
enum ObjectType {
ArrayBuffer,
ElementArrayBuffer
};
BufferObject(ObjectType type = ArrayBuffer);
~BufferObject();
/** Get the type of the buffer object. */
ObjectType type() const;
/** Get the handle of the buffer object. */
int handle() const;
/** Determine if the buffer object is ready to be used. */
bool ready() const { return m_dirty == false; }
/**
* Upload data to the buffer object. The BufferObject::type() must match
* @a type or be uninitialized.
*
* The T type must have tightly packed values of T::value_type accessible by
* reference via T::operator[]. Additionally, the standard size() and empty()
* methods must be implemented. The std::vector class is an example of such a
* supported containers.
*/
template <class T>
bool upload(const T &array, ObjectType type);
/**
* Bind the buffer object ready for rendering.
* @note Only one ARRAY_BUFFER and one ELEMENT_ARRAY_BUFFER may be bound at
* any time.
*/
bool bind();
/**
* Release the buffer. This should be done after rendering is complete.
*/
bool release();
/**
* Return a string describing errors.
*/
std::string error() const { return m_error; }
private:
bool uploadInternal(const void *buffer, size_t size, ObjectType objectType);
struct Private;
Private *d;
bool m_dirty;
std::string m_error;
};
template <class T>
inline bool BufferObject::upload(const T &array,
BufferObject::ObjectType objectType)
{
if (array.empty()) {
m_error = "Refusing to upload empty array.";
return false;
}
return uploadInternal(&array[0],
array.size() * sizeof(typename T::value_type),
objectType);
}
}
#endif
/*=========================================================================
Program: Visualization Toolkit
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.
=========================================================================*/
#ifndef __vtkglMatrix_h
#define __vtkglMatrix_h
#include <Eigen/Dense>
namespace vtkgl {
/** Typedefs for vector types. */
typedef Eigen::Matrix<double, 2, 2> Matrix2;
typedef Eigen::Matrix<double, 3, 3> Matrix3;
typedef Eigen::Matrix<double, 4, 4> Matrix4;
typedef Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> MatrixX;
typedef Eigen::Matrix<float, 2, 2> Matrix2f;
typedef Eigen::Matrix<float, 3, 3> Matrix3f;
typedef Eigen::Matrix<float, 4, 4> Matrix4f;
typedef Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic> MatrixXf;
}
#endif
/*=========================================================================
Program: Visualization Toolkit
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 "vtkglShader.h"
#include <GL/glew.h>
namespace vtkgl {
Shader::Shader(Type type_, const std::string &source_)
: m_type(type_), m_handle(0), m_dirty(true), m_source(source_)
{
}
Shader::~Shader()
{
}
void Shader::setType(Type type_)
{
m_type = type_;
m_dirty = true;
}
void Shader::setSource(const std::string &source_)
{
m_source = source_;
m_dirty = true;
}
bool Shader::compile()
{
if (m_source.empty() || m_type == Unknown || !m_dirty)
return false;
// Ensure we delete the previous shader if necessary.
if (m_handle != 0) {
glDeleteShader(static_cast<GLuint>(m_handle));
m_handle = 0;
}
GLenum type_ = m_type == Vertex ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER;
GLuint handle_ = glCreateShader(type_);
const GLchar *source_ = static_cast<const GLchar *>(m_source.c_str());
glShaderSource(handle_, 1, &source_, NULL);
glCompileShader(handle_);
GLint isCompiled;
glGetShaderiv(handle_, GL_COMPILE_STATUS, &isCompiled);
// Handle shader compilation failures.
if (!isCompiled) {
GLint length(0);
glGetShaderiv(handle_, GL_INFO_LOG_LENGTH, &length);
if (length > 1) {
char *logMessage = new char[length];
glGetShaderInfoLog(handle_, length, NULL, logMessage);
m_error = logMessage;
delete[] logMessage;
}
glDeleteShader(handle_);
return false;
}
// The shader compiled, store its handle and return success.
m_handle = static_cast<int>(handle_);
m_dirty = false;
return true;
}
void Shader::cleanup()
{
if (m_type == Unknown || m_handle == 0)
return;
glDeleteShader(static_cast<GLuint>(m_handle));
m_handle = 0;
m_dirty = false;
}
}
/*=========================================================================
Program: Visualization Toolkit
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.
=========================================================================*/
#ifndef __vtkglShader_h
#define __vtkglShader_h
#include "vtkRenderingOpenGL2Module.h"
#include <string> // For member variables.
namespace vtkgl {
/**
* @brief Vertex or Fragment shader, combined into a ShaderProgram.
*
* This class creates a Vertex or Fragment shader, that can be attached to a
* ShaderProgram in order to render geometry etc.
*/
class VTKRENDERINGOPENGL2_EXPORT Shader
{
public:
/** Available shader types. */
enum Type {
Vertex, /**< Vertex shader */
Fragment, /**< Fragment shader */
Unknown /**< Unknown (default) */
};
explicit Shader(Type type = Unknown, const std::string &source = "");
~Shader();
/** Set the shader type. */
void setType(Type type);
/** Get the shader type, typically Vertex or Fragment. */
Type type() const { return m_type; }
/** Set the shader source to the supplied string. */
void setSource(const std::string &source);
/** Get the source for the shader. */
std::string source() const { return m_source; }
/** Get the error message (empty if none) for the shader. */
std::string error() const { return m_error; }
/** Get the handle of the shader. */
int handle() const { return m_handle; }
/** Compile the shader.
* @note A valid context must to current in order to compile the shader.
*/
bool compile();
/** Delete the shader.
* @note This should only be done once the ShaderProgram is done with the
* Shader.
*/
void cleanup();
protected:
Type m_type;
int m_handle;
bool m_dirty;
std::string m_source;
std::string m_error;
};
}
#endif
This diff is collapsed.
/*=========================================================================
Program: Visualization Toolkit
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.
=========================================================================*/
#ifndef __vtkglShaderProgram_h
#define __vtkglShaderProgram_h
#include "vtkRenderingOpenGL2Module.h"
#include "vtkglVector.h" // For API
#include "vtkglMatrix.h" // For API
#include "vtkVector.h" // For API
#include "vtkColor.h" // For API
#include "vtkTypeTraits.h" // For type traits inline template
#include <string> // For member variables.
#include <vector> // For member variables.
#include <map> // For member variables.
namespace vtkgl {
class Shader;
class Texture2D;
/**
* @brief The ShaderProgram uses one or more Shader objects.
*
* This class creates a Vertex or Fragment shader, that can be attached to a
* ShaderProgram in order to render geometry etc.
*/
class VTKRENDERINGOPENGL2_EXPORT ShaderProgram
{
public:
/** Options for attribute normalization. */