138 lines
No EOL
5.3 KiB
C++
138 lines
No EOL
5.3 KiB
C++
/*
|
|
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;
|
|
};
|
|
}
|
|
} |