CGI/common/include/gui/GLShader.h

138 lines
5.3 KiB
C
Raw Normal View History

2018-09-06 12:35:43 +00:00
/*
This file is part of NSEssentials.
Use of this source code is granted via a BSD-style license, which can be found
in License.txt in the repository root.
@author Wenzel Jakob
@author Nico Schertler
*/
#pragma once
//Adapted nanogui shader
#include <nanogui/glutil.h>
#include <string>
namespace nse {
namespace gui
{
//Represents an OpenGL shader program
class GLShader
{
public:
/// Create an unitialized OpenGL shader program
GLShader()
: mVertexShader(0), mFragmentShader(0), mGeometryShader(0),
mProgramShader(0) { }
~GLShader();
/// Initialize the shader using the specified source strings
bool init(const std::string &name, const std::string &vertex_str,
const std::string &fragment_str,
const std::string &geometry_str = "",
bool failSilently = false);
#ifdef HAVE_TESSELLATION
bool initWithTessellation(const std::string &name, const std::string &vertex_str,
const std::string &tessellation_control_str,
const std::string &tessellation_eval_str,
const std::string &fragment_str,
const std::string &geometry_str = "",
bool failSilently = false);
#endif
/// Initialize the shader using the specified files on disk
bool initFromFiles(const std::string &name,
const std::string &vertex_fname,
const std::string &fragment_fname,
const std::string &geometry_fname = "");
/// Return the name of the shader
const std::string &name() const { return mName; }
/// Set a preprocessor definition
void define(const std::string &key, const std::string &value) { mDefinitions[key] = value; }
/// Select this shader for subsequent draw calls
void bind();
/// Return the handle of a named shader attribute (-1 if it does not exist)
GLint attrib(const std::string &name, bool warn = true) const;
/// Return the handle of a uniform attribute (-1 if it does not exist)
GLint uniform(const std::string &name, bool warn = true) const;
/// Initialize a uniform parameter with a 4x4 matrix (float)
template <typename T>
void setUniform(const std::string &name, const Eigen::Matrix<T, 4, 4> &mat, bool warn = true) {
glUniformMatrix4fv(uniform(name, warn), 1, GL_FALSE, mat.template cast<float>().data());
}
/// Initialize a uniform parameter with an integer value
template <typename T, typename std::enable_if<nanogui::detail::type_traits<T>::integral == 1, int>::type = 0>
void setUniform(const std::string &name, T value, bool warn = true) {
glUniform1i(uniform(name, warn), (int)value);
}
/// Initialize a uniform parameter with a floating point value
template <typename T, typename std::enable_if<nanogui::detail::type_traits<T>::integral == 0, int>::type = 0>
void setUniform(const std::string &name, T value, bool warn = true) {
glUniform1f(uniform(name, warn), (float)value);
}
/// Initialize a uniform parameter with a 2D vector (int)
template <typename T, typename std::enable_if<nanogui::detail::type_traits<T>::integral == 1, int>::type = 0>
void setUniform(const std::string &name, const Eigen::Matrix<T, 2, 1> &v, bool warn = true) {
glUniform2i(uniform(name, warn), (int)v.x(), (int)v.y());
}
/// Initialize a uniform parameter with a 2D vector (float)
template <typename T, typename std::enable_if<nanogui::detail::type_traits<T>::integral == 0, int>::type = 0>
void setUniform(const std::string &name, const Eigen::Matrix<T, 2, 1> &v, bool warn = true) {
glUniform2f(uniform(name, warn), (float)v.x(), (float)v.y());
}
/// Initialize a uniform parameter with a 3D vector (int)
template <typename T, typename std::enable_if<nanogui::detail::type_traits<T>::integral == 1, int>::type = 0>
void setUniform(const std::string &name, const Eigen::Matrix<T, 3, 1> &v, bool warn = true) {
glUniform3i(uniform(name, warn), (int)v.x(), (int)v.y(), (int)v.z());
}
/// Initialize a uniform parameter with a 3D vector (float)
template <typename T, typename std::enable_if<nanogui::detail::type_traits<T>::integral == 0, int>::type = 0>
void setUniform(const std::string &name, const Eigen::Matrix<T, 3, 1> &v, bool warn = true) {
glUniform3f(uniform(name, warn), (float)v.x(), (float)v.y(), (float)v.z());
}
/// Initialize a uniform parameter with a 4D vector (int)
template <typename T, typename std::enable_if<nanogui::detail::type_traits<T>::integral == 1, int>::type = 0>
void setUniform(const std::string &name, const Eigen::Matrix<T, 4, 1> &v, bool warn = true) {
glUniform4i(uniform(name, warn), (int)v.x(), (int)v.y(), (int)v.z(), (int)v.w());
}
/// Initialize a uniform parameter with a 4D vector (float)
template <typename T, typename std::enable_if<nanogui::detail::type_traits<T>::integral == 0, int>::type = 0>
void setUniform(const std::string &name, const Eigen::Matrix<T, 4, 1> &v, bool warn = true) {
glUniform4f(uniform(name, warn), (float)v.x(), (float)v.y(), (float)v.z(), (float)v.w());
}
//Returns the shader program that has been bound last.
static GLShader* currentProgram();
protected:
static GLShader* _currentProgram;
std::string mName;
GLuint mVertexShader;
GLuint mTessellationControlShader;
GLuint mTessellationEvalShader;
GLuint mFragmentShader;
GLuint mGeometryShader;
GLuint mProgramShader;
std::map<std::string, std::string> mDefinitions;
};
}
}