Files
deighton-ar/mobile/ios/ViroKit.framework/Headers/VROUniform.h
2018-03-27 17:46:15 -07:00

349 lines
7.9 KiB
C++

//
// VROUniform.h
// ViroRenderer
//
// Created by Raj Advani on 10/14/16.
// Copyright © 2016 Viro Media. All rights reserved.
//
#ifndef VROUNIFORM_H_
#define VROUNIFORM_H_
#include <string>
#include <memory>
#include "VROVector3f.h"
#include "VROVector4f.h"
#include "VROMatrix4f.h"
#include "VROLog.h"
#include "VROOpenGL.h"
class VROShaderModifier;
class VROGeometry;
class VROMaterial;
/*
The various types of properties that may be set for a shader.
*/
enum class VROShaderProperty {
Bool,
Int,
Float,
Vec2,
Vec3,
Vec4,
BVec2,
BVec3,
BVec4,
IVec2,
IVec3,
IVec4,
Mat2,
Mat3,
Mat4
};
/*
Wraps around a uniform variable, holding its location in the shader and the glUniform
function needed to set its value.
*/
class VROUniform {
public:
static VROUniform *newUniformForType(const std::string &name, VROShaderProperty type, int arraySize);
VROUniform(const std::string &name) :
_name(name),
_location(-1) {
}
virtual ~VROUniform() {}
const std::string getName() const {
return _name;
}
virtual void set(const void *value, const VROGeometry *geometry, const VROMaterial *material) = 0;
inline void setLocation(int location) {
this->_location = location;
}
virtual void reset() {
//sublcass to reset any cached value
}
void setVec3(VROVector3f value) {
if (_location == -1) {
return;
}
glUniform3f(_location, value.x, value.y, value.z);
}
void setVec4(VROVector4f value) {
if (_location == -1) {
return;
}
glUniform4f(_location, value.x, value.y, value.z, value.w);
}
void setMat4(VROMatrix4f value) {
if (_location == -1) {
return;
}
glUniformMatrix4fv(_location, 1, GL_FALSE, value.getArray());
}
void setInt(int value) {
if (_location == -1) {
return;
}
glUniform1i(_location, value);
}
void setFloat(float value) {
if (_location == -1) {
return;
}
glUniform1f(_location, value);
}
protected:
int _location;
private:
const std::string _name;
};
class VROUniform1i: public VROUniform {
public:
VROUniform1i(const std::string &name, int arraySize) :
VROUniform(name), _arraySize(arraySize), _curValue(0) {
}
void set(const void *value, const VROGeometry *geometry, const VROMaterial *material) {
if (_location == -1) {
return;
}
GLint *val = (GLint *) value;
if (*val != _curValue) {
glUniform1iv(_location, _arraySize, val);
_curValue = *val;
}
}
void reset() {
_curValue = 0;
}
private:
const int _arraySize;
int _curValue;
};
class VROUniform2i: public VROUniform {
public:
VROUniform2i(const std::string &name, int arraySize) :
VROUniform(name), _arraySize(arraySize) {
}
void set(const void *value, const VROGeometry *geometry, const VROMaterial *material) {
//passert (_location != -1);
glUniform2iv(_location, _arraySize, (GLint *) value);
}
private:
const int _arraySize;
};
class VROUniform3i: public VROUniform {
public:
VROUniform3i(const std::string &name, int arraySize) :
VROUniform(name), _arraySize(arraySize) {
}
void set(const void *value, const VROGeometry *geometry, const VROMaterial *material) {
passert (_location != -1);
glUniform3iv(_location, _arraySize, (GLint *) value);
}
private:
const int _arraySize;
};
class VROUniform4i: public VROUniform {
public:
VROUniform4i(const std::string &name, int arraySize) :
VROUniform(name), _arraySize(arraySize) {
}
void set(const void *value, const VROGeometry *geometry, const VROMaterial *material) {
//passert (_location != -1);
glUniform4iv(_location, _arraySize, (GLint *) value);
}
private:
const int _arraySize;
};
class VROUniform1f: public VROUniform {
public:
VROUniform1f(const std::string &name, int arraySize) :
VROUniform(name), _arraySize(arraySize), _curValue(9999) {
}
void set(const void *value, const VROGeometry *geometry, const VROMaterial *material) {
if (_location == -1) {
return;
}
GLfloat *val = (GLfloat *) value;
if (_arraySize > 1 || *val != _curValue) {
glUniform1f(_location, *val);
_curValue = *val;
}
}
void reset() {
_curValue = 9999;
}
private:
const int _arraySize;
float _curValue;
};
class VROUniform2f: public VROUniform {
public:
VROUniform2f(const std::string &name, int arraySize) :
VROUniform(name), _arraySize(arraySize) {
}
void set(const void *value, const VROGeometry *geometry, const VROMaterial *material) {
//passert (_location != -1);
glUniform2fv(_location, _arraySize, (GLfloat *) value);
}
private:
const int _arraySize;
};
class VROUniform3f: public VROUniform {
public:
VROUniform3f(const std::string &name, int arraySize) :
VROUniform(name), _arraySize(arraySize) {
_curValue[0] = 0;
_curValue[1] = 0;
_curValue[2] = 0;
}
void set(const void *value, const VROGeometry *geometry, const VROMaterial *material) {
if (_location == -1) {
return;
}
GLfloat *val = (GLfloat *) value;
if (_arraySize > 1 || memcmp(val, _curValue, sizeof(GLfloat) * 3) != 0) {
glUniform3fv(_location, _arraySize, val);
memcpy(_curValue, val, sizeof(GLfloat) * 3);
}
}
void getCurrentValue(void *result) {
memcpy(result, _curValue, sizeof(float) * 3);
}
void reset() {
_curValue[0] = 0;
_curValue[1] = 0;
_curValue[2] = 0;
}
private:
const int _arraySize;
GLfloat _curValue[3];
};
class VROUniform4f: public VROUniform {
public:
VROUniform4f(const std::string &name, int arraySize) :
VROUniform(name), _arraySize(arraySize) {
}
void set(const void *value, const VROGeometry *geometry, const VROMaterial *material) {
//passert (_location != -1);
glUniform4fv(_location, _arraySize, (GLfloat *) value);
}
private:
const int _arraySize;
};
class VROUniformMat2: public VROUniform {
public:
VROUniformMat2(const std::string &name) :
VROUniform(name) {
}
void set(const void *value, const VROGeometry *geometry, const VROMaterial *material) {
//passert (_location != -1);
glUniformMatrix2fv(_location, 1, GL_FALSE, (GLfloat *) value);
}
};
class VROUniformMat3: public VROUniform {
public:
VROUniformMat3(const std::string &name) :
VROUniform(name) {
}
void set(const void *value, const VROGeometry *geometry, const VROMaterial *material) {
//passert (_location != -1);
glUniformMatrix3fv(_location, 1, GL_FALSE, (GLfloat *) value);
}
};
class VROUniformMat4: public VROUniform {
public:
VROUniformMat4(const std::string &name) :
VROUniform(name) {
}
void set(const void *value, const VROGeometry *geometry, const VROMaterial *material) {
//passert (_location != -1);
glUniformMatrix4fv(_location, 1, GL_FALSE, (GLfloat *) value);
}
};
class VROUniformShaderModifier : public VROUniform {
public:
VROUniformShaderModifier(const std::string &name, std::shared_ptr<VROShaderModifier> modifier) :
VROUniform(name),
_modifier(modifier) {
}
void set(const void *value, const VROGeometry *geometry, const VROMaterial *material);
private:
std::shared_ptr<VROShaderModifier> _modifier;
};
#endif