2015-12-20 05:42:54 +01:00
|
|
|
/* ScummVM - Graphic Adventure Engine
|
|
|
|
*
|
|
|
|
* ScummVM is the legal property of its developers, whose names
|
|
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
|
|
* file distributed with this source distribution.
|
|
|
|
*
|
2021-12-26 18:47:58 +01:00
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
2015-12-20 05:42:54 +01:00
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
2021-12-26 18:47:58 +01:00
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2015-12-20 05:42:54 +01:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef BACKENDS_GRAPHICS_OPENGL_SHADER_H
|
|
|
|
#define BACKENDS_GRAPHICS_OPENGL_SHADER_H
|
|
|
|
|
2022-04-25 15:36:50 +02:00
|
|
|
#include "graphics/opengl/system_headers.h"
|
2015-12-20 05:42:54 +01:00
|
|
|
|
2015-12-20 09:30:11 +01:00
|
|
|
#if !USE_FORCED_GLES
|
2015-12-20 05:42:54 +01:00
|
|
|
|
2016-01-04 07:07:37 +01:00
|
|
|
#include "common/singleton.h"
|
2016-03-02 15:16:05 +01:00
|
|
|
#include "common/hash-str.h"
|
|
|
|
#include "common/ptr.h"
|
2015-12-20 05:42:54 +01:00
|
|
|
|
2022-04-25 15:36:50 +02:00
|
|
|
// This is an addition from us to alias ARB shader object extensions to
|
|
|
|
// OpenGL (ES) 2.0 style functions. It only works when GLhandleARB and GLuint
|
|
|
|
// are type compatible.
|
|
|
|
typedef GLuint GLprogram;
|
|
|
|
typedef GLuint GLshader;
|
|
|
|
|
2015-12-20 05:42:54 +01:00
|
|
|
namespace OpenGL {
|
|
|
|
|
2016-03-02 15:16:05 +01:00
|
|
|
/**
|
|
|
|
* A generic uniform value interface for a shader program.
|
|
|
|
*/
|
|
|
|
class ShaderUniformValue {
|
|
|
|
public:
|
|
|
|
virtual ~ShaderUniformValue() {}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Setup the the value to the given location.
|
|
|
|
*
|
|
|
|
* @param location Location of the uniform.
|
|
|
|
*/
|
|
|
|
virtual void set(GLint location) const = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Integer value for a shader uniform.
|
|
|
|
*/
|
|
|
|
class ShaderUniformInteger : public ShaderUniformValue {
|
|
|
|
public:
|
|
|
|
ShaderUniformInteger(GLint value) : _value(value) {}
|
|
|
|
|
2021-11-13 23:18:12 +02:00
|
|
|
void set(GLint location) const override;
|
2016-03-02 15:16:05 +01:00
|
|
|
|
|
|
|
private:
|
|
|
|
const GLint _value;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Float value for a shader uniform.
|
|
|
|
*/
|
|
|
|
class ShaderUniformFloat : public ShaderUniformValue {
|
|
|
|
public:
|
|
|
|
ShaderUniformFloat(GLfloat value) : _value(value) {}
|
|
|
|
|
2021-11-13 23:18:12 +02:00
|
|
|
void set(GLint location) const override;
|
2016-03-02 15:16:05 +01:00
|
|
|
|
|
|
|
private:
|
|
|
|
const GLfloat _value;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 4x4 Matrix value for a shader uniform.
|
|
|
|
*/
|
|
|
|
class ShaderUniformMatrix44 : public ShaderUniformValue {
|
|
|
|
public:
|
|
|
|
ShaderUniformMatrix44(const GLfloat *mat44) {
|
|
|
|
memcpy(_matrix, mat44, sizeof(_matrix));
|
|
|
|
}
|
|
|
|
|
2021-11-13 23:18:12 +02:00
|
|
|
void set(GLint location) const override;
|
2016-03-02 15:16:05 +01:00
|
|
|
|
|
|
|
private:
|
|
|
|
GLfloat _matrix[4*4];
|
|
|
|
};
|
|
|
|
|
2015-12-20 05:42:54 +01:00
|
|
|
class Shader {
|
|
|
|
public:
|
2015-12-21 06:35:13 +01:00
|
|
|
Shader(const Common::String &vertex, const Common::String &fragment);
|
|
|
|
~Shader();
|
2015-12-20 05:42:54 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Destroy the shader program.
|
|
|
|
*
|
|
|
|
* This keeps the vertex and fragment shader sources around and thus
|
2016-03-02 15:16:05 +01:00
|
|
|
* allows for recreating the shader on context recreation. It also keeps
|
|
|
|
* the uniform state around.
|
2015-12-20 05:42:54 +01:00
|
|
|
*/
|
2015-12-21 06:35:13 +01:00
|
|
|
void destroy();
|
2015-12-20 05:42:54 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Recreate shader program.
|
|
|
|
*
|
|
|
|
* @return true on success, false on failure.
|
|
|
|
*/
|
2015-12-21 06:35:13 +01:00
|
|
|
bool recreate();
|
2015-12-20 05:42:54 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Make shader active.
|
|
|
|
*/
|
2016-03-02 15:16:05 +01:00
|
|
|
void activate();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Make shader inactive.
|
|
|
|
*/
|
|
|
|
void deactivate();
|
2016-01-02 14:09:41 +01:00
|
|
|
|
2016-03-04 00:14:22 +01:00
|
|
|
/**
|
|
|
|
* Return location for attribute with given name.
|
|
|
|
*
|
|
|
|
* @param name Name of the attribute to look up in the shader.
|
|
|
|
* @return The loctaion of -1 if attribute was not found.
|
|
|
|
*/
|
|
|
|
GLint getAttributeLocation(const char *name) const;
|
2016-03-04 15:08:10 +01:00
|
|
|
GLint getAttributeLocation(const Common::String &name) const {
|
|
|
|
return getAttributeLocation(name.c_str());
|
|
|
|
}
|
2016-03-04 00:14:22 +01:00
|
|
|
|
2016-01-02 14:09:41 +01:00
|
|
|
/**
|
|
|
|
* Return location for uniform with given name.
|
|
|
|
*
|
|
|
|
* @param name Name of the uniform to look up in the shader.
|
|
|
|
* @return The location or -1 if uniform was not found.
|
|
|
|
*/
|
|
|
|
GLint getUniformLocation(const char *name) const;
|
2016-03-04 15:08:10 +01:00
|
|
|
GLint getUniformLocation(const Common::String &name) const {
|
|
|
|
return getUniformLocation(name.c_str());
|
|
|
|
}
|
2016-01-02 14:09:41 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Bind value to uniform.
|
|
|
|
*
|
2016-03-02 15:16:05 +01:00
|
|
|
* @param name The name of the uniform to be set.
|
|
|
|
* @param value The value to be set.
|
|
|
|
* @return 'false' on error (i.e. uniform unknown or otherwise),
|
|
|
|
* 'true' otherwise.
|
|
|
|
*/
|
|
|
|
bool setUniform(const Common::String &name, ShaderUniformValue *value);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Bind integer value to uniform.
|
2016-01-02 14:09:41 +01:00
|
|
|
*
|
2016-03-02 15:16:05 +01:00
|
|
|
* @param name The name of the uniform to be set.
|
|
|
|
* @param value The value to be set.
|
|
|
|
* @return 'false' on error (i.e. uniform unknown or otherwise),
|
|
|
|
* 'true' otherwise.
|
2016-01-02 14:09:41 +01:00
|
|
|
*/
|
2016-03-02 15:16:05 +01:00
|
|
|
bool setUniform1I(const Common::String &name, GLint value) {
|
|
|
|
return setUniform(name, new ShaderUniformInteger(value));
|
|
|
|
}
|
2015-12-20 09:30:11 +01:00
|
|
|
protected:
|
2015-12-20 05:42:54 +01:00
|
|
|
/**
|
|
|
|
* Vertex shader sources.
|
|
|
|
*/
|
|
|
|
const Common::String _vertex;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Fragment shader sources.
|
|
|
|
*/
|
|
|
|
const Common::String _fragment;
|
2015-12-20 09:30:11 +01:00
|
|
|
|
2016-03-02 15:16:05 +01:00
|
|
|
/**
|
|
|
|
* Whether the shader is active or not.
|
|
|
|
*/
|
|
|
|
bool _isActive;
|
|
|
|
|
2015-12-20 09:30:11 +01:00
|
|
|
/**
|
|
|
|
* Shader program handle.
|
|
|
|
*/
|
2015-12-21 06:35:13 +01:00
|
|
|
GLprogram _program;
|
2015-12-20 09:30:11 +01:00
|
|
|
|
|
|
|
/**
|
2016-03-02 15:16:05 +01:00
|
|
|
* A uniform descriptor.
|
|
|
|
*
|
|
|
|
* This stores the state of a shader uniform. The state is made up of the
|
|
|
|
* uniform location, whether the state was altered since last set, and the
|
|
|
|
* value of the uniform.
|
2015-12-20 09:30:11 +01:00
|
|
|
*/
|
2016-03-02 15:16:05 +01:00
|
|
|
struct Uniform {
|
|
|
|
Uniform() : location(-1), altered(false), value() {}
|
|
|
|
Uniform(GLint loc, ShaderUniformValue *val)
|
|
|
|
: location(loc), altered(true), value(val) {}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Write uniform value into currently active shader.
|
|
|
|
*/
|
|
|
|
void set() {
|
|
|
|
if (altered && value) {
|
|
|
|
value->set(location);
|
|
|
|
altered = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The location of the uniform or -1 in case it does not exist.
|
|
|
|
*/
|
|
|
|
GLint location;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Whether the uniform state was aletered since last 'set'.
|
|
|
|
*/
|
|
|
|
bool altered;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The value of the uniform.
|
|
|
|
*/
|
|
|
|
Common::SharedPtr<ShaderUniformValue> value;
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef Common::HashMap<Common::String, Uniform> UniformMap;
|
2015-12-20 09:30:11 +01:00
|
|
|
|
|
|
|
/**
|
2016-03-02 15:16:05 +01:00
|
|
|
* Map from uniform name to associated uniform description.
|
2015-12-20 09:30:11 +01:00
|
|
|
*/
|
2016-03-02 15:16:05 +01:00
|
|
|
UniformMap _uniforms;
|
2015-12-20 09:30:11 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Compile a vertex or fragment shader.
|
|
|
|
*
|
|
|
|
* @param source Sources to the shader.
|
|
|
|
* @param shaderType Type of shader to compile (GL_FRAGMENT_SHADER_ARB or
|
|
|
|
* GL_VERTEX_SHADER_ARB)
|
|
|
|
* @return The shader object or 0 on failure.
|
|
|
|
*/
|
2015-12-21 06:35:13 +01:00
|
|
|
static GLshader compileShader(const char *source, GLenum shaderType);
|
2015-12-20 05:42:54 +01:00
|
|
|
};
|
|
|
|
|
2016-01-04 07:07:37 +01:00
|
|
|
class ShaderManager : public Common::Singleton<ShaderManager> {
|
|
|
|
public:
|
|
|
|
enum ShaderUsage {
|
|
|
|
/** Default shader implementing the GL fixed-function pipeline. */
|
|
|
|
kDefault = 0,
|
|
|
|
|
|
|
|
/** CLUT8 look up shader. */
|
|
|
|
kCLUT8LookUp,
|
|
|
|
|
|
|
|
/** Number of built-in shaders. Should not be used for query. */
|
|
|
|
kMaxUsages
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Notify shader manager about context destruction.
|
|
|
|
*/
|
|
|
|
void notifyDestroy();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Notify shader manager about context creation.
|
|
|
|
*/
|
|
|
|
void notifyCreate();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Query a built-in shader.
|
|
|
|
*/
|
|
|
|
Shader *query(ShaderUsage shader) const;
|
|
|
|
|
|
|
|
private:
|
|
|
|
friend class Common::Singleton<SingletonBaseType>;
|
|
|
|
ShaderManager();
|
|
|
|
~ShaderManager();
|
|
|
|
|
2016-03-02 15:16:05 +01:00
|
|
|
bool _initializeShaders;
|
|
|
|
|
2016-01-04 07:07:37 +01:00
|
|
|
Shader *_builtIn[kMaxUsages];
|
|
|
|
};
|
|
|
|
|
2015-12-20 05:42:54 +01:00
|
|
|
} // End of namespace OpenGL
|
|
|
|
|
2016-01-04 07:07:37 +01:00
|
|
|
/** Shortcut for accessing the font manager. */
|
|
|
|
#define ShaderMan (OpenGL::ShaderManager::instance())
|
|
|
|
|
2015-12-20 09:30:11 +01:00
|
|
|
#endif // !USE_FORCED_GLES
|
2015-12-20 05:42:54 +01:00
|
|
|
|
|
|
|
#endif
|