Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

View File

@@ -0,0 +1,48 @@
/* 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.
*
* 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.
*
* 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
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "backends/graphics/opengl/pipelines/clut8.h"
#include "backends/graphics/opengl/shader.h"
#include "backends/graphics/opengl/framebuffer.h"
#include "graphics/opengl/debug.h"
namespace OpenGL {
#if !USE_FORCED_GLES
CLUT8LookUpPipeline::CLUT8LookUpPipeline()
: ShaderPipeline(ShaderMan.query(ShaderManager::kCLUT8LookUp)), _paletteTexture(nullptr) {
}
void CLUT8LookUpPipeline::drawTextureInternal(const Texture &texture, const GLfloat *coordinates, const GLfloat *texcoords) {
assert(isActive());
// Set the palette texture.
GL_CALL(glActiveTexture(GL_TEXTURE1));
if (_paletteTexture) {
_paletteTexture->bind();
}
GL_CALL(glActiveTexture(GL_TEXTURE0));
ShaderPipeline::drawTextureInternal(texture, coordinates, texcoords);
}
#endif // !USE_FORCED_GLES
} // End of namespace OpenGL

View File

@@ -0,0 +1,46 @@
/* 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.
*
* 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.
*
* 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
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BACKENDS_GRAPHICS_OPENGL_PIPELINES_CLUT8_H
#define BACKENDS_GRAPHICS_OPENGL_PIPELINES_CLUT8_H
#include "backends/graphics/opengl/pipelines/shader.h"
namespace OpenGL {
#if !USE_FORCED_GLES
class CLUT8LookUpPipeline : public ShaderPipeline {
public:
CLUT8LookUpPipeline();
void setPaletteTexture(const Texture *paletteTexture) { _paletteTexture = paletteTexture; }
protected:
void drawTextureInternal(const Texture &texture, const GLfloat *coordinates, const GLfloat *texcoords) override;
private:
const Texture *_paletteTexture;
};
#endif // !USE_FORCED_GLES
} // End of namespace OpenGL
#endif

View File

@@ -0,0 +1,88 @@
/* 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.
*
* 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.
*
* 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
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "backends/graphics/opengl/pipelines/fixed.h"
#include "graphics/opengl/debug.h"
namespace OpenGL {
#if !USE_FORCED_GLES2
void FixedPipeline::activateInternal() {
Pipeline::activateInternal();
// Disable 3D properties.
GL_CALL(glDisable(GL_CULL_FACE));
GL_CALL(glDisable(GL_DEPTH_TEST));
GL_CALL(glDisable(GL_DITHER));
GL_CALL(glDisable(GL_LIGHTING));
GL_CALL(glDisable(GL_FOG));
GL_CALL(glShadeModel(GL_FLAT));
GL_CALL(glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST));
GL_CALL(glEnableClientState(GL_VERTEX_ARRAY));
GL_CALL(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
#if !USE_FORCED_GLES
if (OpenGLContext.multitextureSupported) {
GL_CALL(glActiveTexture(GL_TEXTURE0));
}
#endif
GL_CALL(glEnable(GL_TEXTURE_2D));
GL_CALL(glColor4f(_r, _g, _b, _a));
}
void FixedPipeline::setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
_r = r;
_g = g;
_b = b;
_a = a;
if (isActive()) {
GL_CALL(glColor4f(r, g, b, a));
}
}
void FixedPipeline::drawTextureInternal(const Texture &texture, const GLfloat *coordinates, const GLfloat *texcoords) {
assert(isActive());
texture.bind();
GL_CALL(glTexCoordPointer(2, GL_FLOAT, 0, texcoords));
GL_CALL(glVertexPointer(2, GL_FLOAT, 0, coordinates));
GL_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
}
void FixedPipeline::setProjectionMatrix(const Math::Matrix4 &projectionMatrix) {
assert(isActive());
GL_CALL(glMatrixMode(GL_PROJECTION));
GL_CALL(glLoadMatrixf(projectionMatrix.getData()));
GL_CALL(glMatrixMode(GL_MODELVIEW));
GL_CALL(glLoadIdentity());
GL_CALL(glMatrixMode(GL_TEXTURE));
GL_CALL(glLoadIdentity());
}
#endif // !USE_FORCED_GLES2
} // End of namespace OpenGL

View File

@@ -0,0 +1,48 @@
/* 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.
*
* 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.
*
* 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
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BACKENDS_GRAPHICS_OPENGL_PIPELINES_FIXED_H
#define BACKENDS_GRAPHICS_OPENGL_PIPELINES_FIXED_H
#include "backends/graphics/opengl/pipelines/pipeline.h"
namespace OpenGL {
#if !USE_FORCED_GLES2
class FixedPipeline : public Pipeline {
public:
FixedPipeline() : _r(0.f), _g(0.f), _b(0.f), _a(0.f) {}
void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) override;
void setProjectionMatrix(const Math::Matrix4 &projectionMatrix) override;
protected:
void activateInternal() override;
void drawTextureInternal(const Texture &texture, const GLfloat *coordinates, const GLfloat *texcoords) override;
GLfloat _r, _g, _b, _a;
};
#endif // !USE_FORCED_GLES2
} // End of namespace OpenGL
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,277 @@
/* 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.
*
* 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.
*
* 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
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BACKENDS_GRAPHICS_OPENGL_PIPELINES_LIBRETRO_H
#define BACKENDS_GRAPHICS_OPENGL_PIPELINES_LIBRETRO_H
#include "graphics/opengl/system_headers.h"
#if !USE_FORCED_GLES
#include "backends/graphics/opengl/pipelines/shader.h"
#include "common/array.h"
#include "common/fs.h"
namespace Graphics {
struct Surface;
}
namespace OpenGL {
namespace LibRetro {
struct ShaderPreset;
struct ShaderPass;
} // End of namespace LibRetro
class TextureTarget;
class LibRetroTextureTarget;
/**
* Pipeline implementation using Libretro shader presets.
*/
class LibRetroPipeline : public Pipeline {
public:
LibRetroPipeline();
~LibRetroPipeline() override;
void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) override;
void setProjectionMatrix(const Math::Matrix4 &projectionMatrix) override;
bool open(const Common::Path &shaderPath, Common::SearchSet &archSet);
void close();
/* Called by OpenGLGraphicsManager */
void enableLinearFiltering(bool enabled) { _linearFiltering = enabled; }
void setRotation(Common::RotationMode rotation) { if (_rotation != rotation) { _rotation = rotation; setPipelineState(); } }
/* Called by OpenGLGraphicsManager to setup the internal objects sizes */
void setDisplaySizes(uint inputWidth, uint inputHeight, const Common::Rect &outputRect);
/* Called by OpenGLGraphicsManager to indicate that next draws need to be scaled. */
void beginScaling();
/* Called by OpenGLGraphicsManager to indicate that next draws don't need to be scaled.
* This must be called to execute scaling. */
void finishScaling();
bool isAnimated() const { return _isAnimated; }
static bool isSupportedByContext() {
return OpenGLContext.shadersSupported
&& OpenGLContext.multitextureSupported
&& OpenGLContext.framebufferObjectSupported;
}
private:
void activateInternal() override;
void deactivateInternal() override;
void drawTextureInternal(const Texture &texture, const GLfloat *coordinates, const GLfloat *texcoords) override;
bool loadTextures(Common::SearchSet &archSet);
bool loadPasses(Common::SearchSet &archSet);
void setPipelineState();
bool setupFBOs();
void setupPassUniforms(const uint id);
void setShaderTexUniforms(const Common::String &prefix, Shader *shader, const Texture &texture);
/* Pipelines used to draw all layers
* First before the scaler then after it to draw on screen
*/
ShaderPipeline _inputPipeline;
ShaderPipeline _outputPipeline;
bool _needsScaling;
const LibRetro::ShaderPreset *_shaderPreset;
uint _inputWidth;
uint _inputHeight;
Common::Rect _outputRect;
bool _linearFiltering;
Common::RotationMode _rotation;
/* Determines if preset depends on frameCount or from previous frames */
bool _isAnimated;
uint _frameCount;
Common::Array<LibRetroTextureTarget> _inputTargets;
uint _currentTarget;
struct LibRetroTexture {
LibRetroTexture() : textureData(nullptr), glTexture(nullptr) {}
LibRetroTexture(Graphics::Surface *tD, Texture *glTex) : textureData(tD), glTexture(glTex) {}
Common::String id;
Graphics::Surface *textureData;
Texture *glTexture;
};
LibRetroTexture loadTexture(const Common::Path &fileName, Common::Archive *container, Common::SearchSet &archSet);
typedef Common::Array<LibRetroTexture> TextureArray;
TextureArray _textures;
struct Pass {
Pass()
: shaderPass(nullptr), shader(nullptr), target(nullptr), texCoords(), texSamplers(),
inputTexture(nullptr), vertexCoord(), hasFrameCount(false), prevCount(0) {}
Pass(const LibRetro::ShaderPass *sP, Shader *s, TextureTarget *t)
: shaderPass(sP), shader(s), target(t), texCoords(), texSamplers(),
inputTexture(nullptr), vertexCoord(), hasFrameCount(false), prevCount(0) {}
const LibRetro::ShaderPass *shaderPass;
Shader *shader;
TextureTarget *target;
/**
* Description of texture coordinates bound to attribute.
*/
struct TexCoordAttribute {
/**
* Attribute name to bind data to.
*/
Common::String name;
enum Type {
/**
* 'index' denotes the 'index'th shader texture's coordinates.
*/
kTypeTexture,
/**
* 'index' denotes the texture coordinates given to pass 'index'.
*/
kTypePass,
/**
* 'index' denotes the texture coordinates of the 'index'th previous frame.
*/
kTypePrev
};
/**
* The type of the attribute.
*/
Type type;
/**
* Index for the texture coordinates to use.
*/
uint index;
TexCoordAttribute() : name(), type(), index() {}
TexCoordAttribute(const Common::String &n, Type t, uint i) : name(n), type(t), index(i) {}
};
typedef Common::Array<TexCoordAttribute> TexCoordAttributeArray;
TexCoordAttributeArray texCoords;
/**
* Build the 'texCoords' array.
*
* @param id Identifier of the current pass.
*/
void buildTexCoords(const uint id, const Common::StringArray &aliases);
void addTexCoord(const Common::String &prefix, const TexCoordAttribute::Type type, const uint index);
/**
* Description of a texture sampler.
*/
struct TextureSampler {
/**
* Texture unit to use.
*/
uint unit;
enum Type {
/**
* 'index' denotes the 'index'th shader texture.
*/
kTypeTexture,
/**
* 'index' denotes the input to pass 'index'.
*/
kTypePass,
/**
* 'index' denotes the input of the 'index'th previous frame.
*/
kTypePrev
};
/**
* Source type of the texture to bind.
*/
Type type;
/**
* Index of the texture.
*/
uint index;
TextureSampler() : unit(), type(), index() {}
TextureSampler(uint u, Type t, uint i) : unit(u), type(t), index(i) {}
};
typedef Common::Array<TextureSampler> TextureSamplerArray;
TextureSamplerArray texSamplers;
/**
* Build the 'texSamplers' array.
*
* @param id Identifier of the current pass.
* @param textures Array of shader textures available.
*/
void buildTexSamplers(const uint id, const TextureArray &textures, const Common::StringArray &aliases);
bool addTexSampler(const Common::String &name, uint *unit, const TextureSampler::Type type, const uint index, const bool prefixIsId = false);
/**
* Input texture of the pass.
*/
const Texture *inputTexture;
/**
* Vertex coordinates used for drawing.
*/
GLfloat vertexCoord[2*4];
/**
* Whether the shader has a FrameCount uniform or not
* Allows to speed up if it is not here
*/
bool hasFrameCount;
/**
* The number of previous frames this pass needs
*/
uint prevCount;
};
typedef Common::Array<Pass> PassArray;
PassArray _passes;
void renderPass(const Pass &pass);
void renderPassSetupCoordinates(const Pass &pass);
void renderPassSetupTextures(const Pass &pass);
};
} // End of namespace OpenGL
#endif // !USE_FORCED_GLES
#endif

View File

@@ -0,0 +1,573 @@
/* 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.
*
* 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.
*
* 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
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "graphics/opengl/system_headers.h"
#if !USE_FORCED_GLES
#include "backends/graphics/opengl/pipelines/libretro/parser.h"
#include "common/file.h"
#include "common/hash-str.h"
#include "common/stream.h"
#include "common/algorithm.h"
#include "common/tokenizer.h"
#include "common/ptr.h"
#include "common/util.h"
#include "common/textconsole.h"
namespace OpenGL {
namespace LibRetro {
class PresetParser {
public:
ShaderPreset *parseStream(Common::SeekableReadStream &stream);
const Common::String &getErrorDesc() const { return _errorDesc; }
private:
bool parsePreset(Common::SeekableReadStream &stream);
bool lookUpValue(const Common::String &key, Common::String *value);
bool lookUpValue(const Common::String &key, bool *value);
bool lookUpValue(const Common::String &key, uint *value);
bool lookUpValue(const Common::String &key, float *value);
bool lookUpValue(const Common::String &key, FilteringMode *value, const FilteringMode defaultValue);
bool lookUpValue(const Common::String &key, ScaleType *value, const ScaleType defaultValue);
bool lookUpValueScale(const Common::String &key, float *floatValue, uint *uintValue, const ScaleType scaleType);
bool lookUpValue(const Common::String &key, WrapMode *value, const WrapMode defaultValue);
template<typename T, typename DefaultT>
bool lookUpValue(const Common::String &key, T *value, const DefaultT &defaultValue) {
if (_entries.contains(key)) {
return lookUpValue(key, value);
} else {
*value = defaultValue;
return true;
}
}
bool parseTextures();
bool parseTexture(const Common::String &id);
bool parsePasses();
bool parsePass(const uint id, const bool isLast);
bool parsePassScaleType(const uint id, const bool isLast, ShaderPass *pass);
bool parsePassScale(const uint id, ShaderPass *pass);
bool computeDefaultScale(const Common::String &key, float *floatValue, uint *uintValue, const ScaleType scaleType);
bool parseParameters();
typedef Common::HashMap<Common::String, Common::String> StringMap;
StringMap _entries;
Common::String _errorDesc;
Common::ScopedPtr<ShaderPreset> _shader;
};
ShaderPreset *PresetParser::parseStream(Common::SeekableReadStream &stream) {
_errorDesc.clear();
_entries.clear();
if (!parsePreset(stream)) {
return nullptr;
}
_shader.reset(new ShaderPreset);
if (!parseTextures()) {
return nullptr;
}
if (!parsePasses()) {
return nullptr;
}
if (!parseParameters()) {
return nullptr;
}
return _shader.release();
}
bool PresetParser::parsePreset(Common::SeekableReadStream &stream) {
while (!stream.eos()) {
Common::String line = stream.readLine();
if (stream.err()) {
_errorDesc = "Read error";
return false;
}
size_t sharpPos = line.findFirstOf('#');
if (sharpPos != line.npos) {
// Remove the end of line
line.erase(sharpPos);
}
if (line.empty()) {
continue;
}
bool empty = true;
for (uint i = 0; i < line.size(); i++) {
if (!Common::isSpace(line[i])) {
empty = false;
break;
}
}
if (empty)
continue;
// Split line into key, value pair.
Common::String::const_iterator equalIter = Common::find(line.begin(), line.end(), '=');
if (equalIter == line.end()) {
_errorDesc = "Could not find '=' in line '" + line + '\'';
return false;
}
Common::String key(line.begin(), equalIter);
Common::String value(equalIter + 1);
key.trim();
value.trim();
// Check whether the value is put in quotation marks. This might be
// useful when a path contains a whitespace. But Libretro's is not
// mentioning any exact format, but one example for 'textures'
// indicates quotes are supported in this place.
if (!value.empty() && value[0] == '"') {
if (value.size() < 2 || value.lastChar() != '"') {
_errorDesc = "Unmatched '\"' for value in line '" + line + '\'';
}
value.deleteLastChar();
value.deleteChar(0);
}
_entries[key] = value;
}
return true;
}
bool PresetParser::lookUpValue(const Common::String &key, Common::String *value) {
StringMap::const_iterator iter = _entries.find(key);
if (iter != _entries.end()) {
*value = iter->_value;
return true;
} else {
_errorDesc = "Missing key '" + key + "'";
return false;
}
}
bool PresetParser::lookUpValue(const Common::String &key, bool *value) {
StringMap::const_iterator iter = _entries.find(key);
if (iter != _entries.end()) {
if (Common::parseBool(iter->_value, *value)) {
return true;
} else {
_errorDesc = "Invalid boolean value for key '" + key + "': '" + iter->_value + '\'';
return false;
}
} else {
_errorDesc = "Missing key '" + key + "'";
return false;
}
}
bool PresetParser::lookUpValue(const Common::String &key, uint *value) {
StringMap::const_iterator iter = _entries.find(key);
if (iter != _entries.end()) {
char *endptr;
const unsigned long uintVal = strtoul(iter->_value.c_str(), &endptr, 0);
// Original libretro is quite laxist with int values and only checks errno
// This means that as long as there is some number at start, parsing won't fail
if (endptr == iter->_value.c_str() || uintVal >= UINT_MAX) {
_errorDesc = "Invalid unsigned integer value for key '" + key + "': '" + iter->_value + '\'';
return false;
} else {
if (*endptr != '\0') {
warning("Possibly invalid unsigned integer value for key '%s': '%s'", key.c_str(), iter->_value.c_str());
}
*value = uintVal;
return true;
}
} else {
_errorDesc = "Missing key '" + key + "'";
return false;
}
}
bool PresetParser::lookUpValue(const Common::String &key, float *value) {
StringMap::const_iterator iter = _entries.find(key);
if (iter != _entries.end()) {
char *endptr;
const double doubleVal = strtod(iter->_value.c_str(), &endptr);
if (*endptr != '\0') {
_errorDesc = "Invalid float value for key '" + key + "': '" + iter->_value + '\'';
return false;
} else {
*value = doubleVal;
return true;
}
} else {
_errorDesc = "Missing key '" + key + "'";
return false;
}
}
bool PresetParser::lookUpValue(const Common::String &key, FilteringMode *value, const FilteringMode defaultValue) {
StringMap::const_iterator iter = _entries.find(key);
if (iter != _entries.end()) {
bool isLinear;
if (Common::parseBool(iter->_value, isLinear)) {
*value = isLinear ? kFilteringModeLinear : kFilteringModeNearest;
return true;
} else {
_errorDesc = "Invalid filtering mode for key '" + key + "': '" + iter->_value + '\'';
return false;
}
} else {
*value = defaultValue;
return true;
}
}
bool PresetParser::lookUpValue(const Common::String &key, ScaleType *value, const ScaleType defaultValue) {
StringMap::const_iterator iter = _entries.find(key);
if (iter != _entries.end()) {
if (iter->_value == "source") {
*value = kScaleTypeSource;
return true;
} else if (iter->_value == "viewport") {
*value = kScaleTypeViewport;
return true;
} else if (iter->_value == "absolute") {
*value = kScaleTypeAbsolute;
return true;
} else {
_errorDesc = "Invalid scale type for key '" + key + "': '" + iter->_value + '\'';
return false;
}
} else {
*value = defaultValue;
return true;
}
}
bool PresetParser::lookUpValueScale(const Common::String &key, float *floatValue, uint *uintValue, const ScaleType scaleType) {
switch (scaleType) {
case kScaleTypeSource:
case kScaleTypeViewport:
return lookUpValue(key, floatValue, 1.0f);
case kScaleTypeAbsolute:
return lookUpValue(key, uintValue);
case kScaleTypeFull:
return true;
default:
_errorDesc = "Internal Error: Invalid scale type";
return false;
}
}
bool PresetParser::lookUpValue(const Common::String &key, WrapMode *value, const WrapMode defaultValue) {
StringMap::const_iterator iter = _entries.find(key);
if (iter != _entries.end()) {
if (iter->_value == "clamp_to_border") {
*value = kWrapModeBorder;
return true;
} else if (iter->_value == "clamp_to_edge") {
*value = kWrapModeEdge;
return true;
} else if (iter->_value == "repeat") {
*value = kWrapModeRepeat;
return true;
} else if (iter->_value == "mirrored_repeat") {
*value = kWrapModeMirroredRepeat;
return true;
} else {
_errorDesc = "Invalid wrap mode for key '" + key + "': '" + iter->_value + '\'';
return false;
}
} else {
*value = defaultValue;
return true;
}
}
bool PresetParser::parseTextures() {
Common::String textures;
if (!lookUpValue("textures", &textures)) {
return true;
}
// Parse all texture information from preset.
Common::StringTokenizer tokenizer(textures, ";");
while (!tokenizer.empty()) {
if (!parseTexture(tokenizer.nextToken())) {
return false;
}
}
return true;
}
bool PresetParser::parseTexture(const Common::String &id) {
Common::String fileName;
if (!lookUpValue(id, &fileName)) {
_errorDesc = "No file name specified for texture '" + id + '\'';
return false;
}
FilteringMode filteringMode;
if (!lookUpValue(id + "_linear", &filteringMode, kFilteringModeLinear)) {
return false;
}
WrapMode wrapMode;
if (!lookUpValue(id + "_wrap_mode", &wrapMode, kWrapModeBorder)) {
return false;
}
_shader->textures.push_back(ShaderTexture(id, fileName, filteringMode, wrapMode));
return true;
}
bool PresetParser::parsePasses() {
uint numShaders;
if (!lookUpValue("shaders", &numShaders)) {
return false;
}
for (uint shaderPass = 0; shaderPass < numShaders; ++shaderPass) {
if (!parsePass(shaderPass, shaderPass == numShaders - 1)) {
return false;
}
}
return true;
}
#define passKey(x) Common::String::format(x "%u", id)
bool PresetParser::parsePass(const uint id, const bool isLast) {
ShaderPass pass;
if (!lookUpValue(passKey("shader"), &pass.fileName)) {
_errorDesc = Common::String::format("No file name specified for pass '%u'", id);
return false;
}
if (!lookUpValue(passKey("alias"), &pass.alias)) {
_errorDesc.clear();
pass.alias.clear();
}
if (!lookUpValue(passKey("filter_linear"), &pass.filteringMode, kFilteringModeUnspecified)) {
return false;
}
if (!lookUpValue(passKey("wrap_mode"), &pass.wrapMode, kWrapModeBorder)) {
return false;
}
if (!lookUpValue(passKey("mipmap_input"), &pass.mipmapInput, false)) {
return false;
}
if (!lookUpValue(passKey("float_framebuffer"), &pass.floatFBO, false)) {
return false;
}
if (!lookUpValue(passKey("srgb_framebuffer"), &pass.srgbFBO, false)) {
return false;
}
if (!lookUpValue(passKey("frame_count_mod"), &pass.frameCountMod, 0)) {
return false;
}
if (!parsePassScaleType(id, isLast, &pass)) {
return false;
}
if (!parsePassScale(id, &pass)) {
return false;
}
_shader->passes.push_back(pass);
return true;
}
bool PresetParser::parsePassScaleType(const uint id, const bool isLast, ShaderPass *pass) {
// Parse scale type for the pass.
//
// This is a little more complicated because it is possible to specify the
// scale type per axis. However, a generic scale type overrides the axis
// scale types.
//
// Additionally, the default value for the passes vary. The last pass
// defaults to use full size, all other default to source scaling.
const ScaleType defaultScaleType = isLast ? kScaleTypeFull : kScaleTypeSource;
if (!lookUpValue(passKey("scale_type_x"), &pass->scaleTypeX, defaultScaleType)) {
return false;
}
if (!lookUpValue(passKey("scale_type_y"), &pass->scaleTypeY, defaultScaleType)) {
return false;
}
ScaleType scale_type;
// Small trick here: lookUpValue never returns kScaleTypeFull
if (!lookUpValue(passKey("scale_type"), &scale_type, kScaleTypeFull)) {
return false;
} else if (scale_type != kScaleTypeFull) {
pass->scaleTypeY = pass->scaleTypeX = scale_type;
}
return true;
}
bool PresetParser::parsePassScale(const uint id, ShaderPass *pass) {
// Parse actual scale value for the pass.
//
// Like for the scale type, 'scale' overrides 'scale_x'/'scale_y'.
if (_entries.contains(passKey("scale"))) {
if (!lookUpValueScale(passKey("scale"), &pass->scaleXFloat, &pass->scaleXUint, pass->scaleTypeX)) {
return false;
}
if (!lookUpValueScale(passKey("scale"), &pass->scaleYFloat, &pass->scaleYUint, pass->scaleTypeY)) {
return false;
}
return true;
}
if (_entries.contains(passKey("scale_x"))) {
if (!lookUpValueScale(passKey("scale_x"), &pass->scaleXFloat, &pass->scaleXUint, pass->scaleTypeX)) {
return false;
}
} else {
if (!computeDefaultScale(passKey("scale_x"), &pass->scaleXFloat, &pass->scaleXUint, pass->scaleTypeX)) {
return false;
}
}
if (_entries.contains(passKey("scale_y"))) {
if (!lookUpValueScale(passKey("scale_y"), &pass->scaleYFloat, &pass->scaleYUint, pass->scaleTypeY)) {
return false;
}
} else {
if (!computeDefaultScale(passKey("scale_y"), &pass->scaleYFloat, &pass->scaleYUint, pass->scaleTypeY)) {
return false;
}
}
return true;
}
#undef passKey
bool PresetParser::computeDefaultScale(const Common::String &key, float *floatValue, uint *uintValue, const ScaleType scaleType) {
switch (scaleType) {
case kScaleTypeSource:
case kScaleTypeViewport:
*floatValue = 1.0f;
return true;
case kScaleTypeAbsolute:
_errorDesc = "No value specified for scale '" + key + '\'';
return false;
case kScaleTypeFull:
return true;
default:
_errorDesc = "Internal Error: Invalid scale type";
return false;
}
}
bool PresetParser::parseParameters() {
Common::String parameters;
if (!lookUpValue("parameters", &parameters)) {
return true;
}
// Parse all texture information from preset.
Common::StringTokenizer tokenizer(parameters, ";");
while (!tokenizer.empty()) {
Common::String key = tokenizer.nextToken();
if (_entries.contains(key)) {
float value;
if (!lookUpValue(key, &value)) {
return false;
}
_shader->parameters[key] = value;
}
}
return true;
}
ShaderPreset *parsePreset(const Common::Path &shaderPreset, Common::SearchSet &archSet) {
Common::SeekableReadStream *stream;
Common::Archive *container = nullptr;
Common::Path basePath;
// First try SearchMan, then fallback to filesystem
if (archSet.hasFile(shaderPreset)) {
Common::ArchiveMemberPtr member = archSet.getMember(shaderPreset, &container);
stream = member->createReadStream();
basePath = shaderPreset.getParent();
} else {
Common::FSNode fsnode(shaderPreset);
if (!fsnode.exists() || !fsnode.isReadable() || fsnode.isDirectory()
|| !(stream = fsnode.createReadStream())) {
warning("LibRetro Preset Parsing: Invalid file path '%s'", shaderPreset.toString(Common::Path::kNativeSeparator).c_str());
return nullptr;
}
basePath = fsnode.getParent().getPath();
}
PresetParser parser;
ShaderPreset *shader = parser.parseStream(*stream);
delete stream;
if (!shader) {
warning("LibRetro Preset Parsing: Error while parsing file '%s': %s", shaderPreset.toString().c_str(), parser.getErrorDesc().c_str());
return nullptr;
}
shader->container = container;
shader->basePath = basePath;
return shader;
}
} // End of namespace LibRetro
} // End of namespace OpenGL
#endif // !USE_FORCED_GLES

View File

@@ -0,0 +1,39 @@
/* 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.
*
* 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.
*
* 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
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BACKENDS_GRAPHICS_OPENGL_PIPELINES_LIBRETRO_PARSER_H
#define BACKENDS_GRAPHICS_OPENGL_PIPELINES_LIBRETRO_PARSER_H
#include "graphics/opengl/system_headers.h"
#if !USE_FORCED_GLES
#include "backends/graphics/opengl/pipelines/libretro/types.h"
namespace OpenGL {
namespace LibRetro {
ShaderPreset *parsePreset(const Common::Path &shaderPreset, Common::SearchSet &archSet);
} // End of namespace LibRetro
} // End of namespace OpenGL
#endif // !USE_FORCED_GLES
#endif

View File

@@ -0,0 +1,132 @@
/* 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.
*
* 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.
*
* 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
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BACKENDS_GRAPHICS_OPENGL_PIPELINES_LIBRETRO_TYPES_H
#define BACKENDS_GRAPHICS_OPENGL_PIPELINES_LIBRETRO_TYPES_H
#include "graphics/opengl/system_headers.h"
#include "graphics/opengl/texture.h"
#if !USE_FORCED_GLES
#include "common/str.h"
#include "common/array.h"
#include "common/fs.h"
namespace OpenGL {
namespace LibRetro {
typedef Common::HashMap<Common::String, float, Common::CaseSensitiveString_Hash, Common::CaseSensitiveString_EqualTo> UniformsMap;
enum FilteringMode {
kFilteringModeUnspecified,
kFilteringModeNearest,
kFilteringModeLinear
};
struct ShaderTexture {
ShaderTexture() : id(), fileName(), filteringMode(kFilteringModeUnspecified) {}
ShaderTexture(const Common::String &i, const Common::String &fN, FilteringMode fM, WrapMode wM)
: id(i), fileName(fN), filteringMode(fM), wrapMode(wM) {}
Common::String id;
Common::String fileName;
FilteringMode filteringMode;
WrapMode wrapMode;
};
enum ScaleType {
kScaleTypeSource,
kScaleTypeViewport,
kScaleTypeAbsolute,
kScaleTypeFull
};
inline void applyScale(const ScaleType type,
const float source, const float viewport,
const float scaleFloat, const uint scaleUint,
float *output) {
switch (type) {
case kScaleTypeSource:
*output = source * scaleFloat;
break;
case kScaleTypeViewport:
*output = viewport * scaleFloat;
break;
case kScaleTypeAbsolute:
*output = scaleUint;
break;
case kScaleTypeFull:
*output = viewport;
break;
}
}
struct ShaderPass {
Common::String fileName;
Common::String alias;
FilteringMode filteringMode;
WrapMode wrapMode;
bool mipmapInput;
bool floatFBO;
bool srgbFBO;
uint frameCountMod;
ScaleType scaleTypeX;
ScaleType scaleTypeY;
float scaleXFloat;
float scaleYFloat;
uint scaleXUint;
uint scaleYUint;
void applyScale(const float sourceW, const float sourceH,
const float viewportW, const float viewportH,
float *outputW, float *outputH) const {
OpenGL::LibRetro::applyScale(scaleTypeX, sourceW, viewportW, scaleXFloat, scaleXUint, outputW);
OpenGL::LibRetro::applyScale(scaleTypeY, sourceH, viewportH, scaleYFloat, scaleYUint, outputH);
}
};
struct ShaderPreset {
Common::Archive *container;
Common::Path basePath;
typedef Common::Array<ShaderTexture> TextureArray;
TextureArray textures;
typedef Common::Array<ShaderPass> PassArray;
PassArray passes;
UniformsMap parameters;
};
} // End of namespace LibRetro
} // End of namespace OpenGL
#endif // !USE_FORCED_GLES
#endif

View File

@@ -0,0 +1,81 @@
/* 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.
*
* 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.
*
* 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
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "backends/graphics/opengl/pipelines/pipeline.h"
#include "backends/graphics/opengl/framebuffer.h"
namespace OpenGL {
Pipeline *Pipeline::activePipeline = nullptr;
Pipeline::Pipeline()
: _activeFramebuffer(nullptr) {
}
void Pipeline::activate() {
if (activePipeline == this) {
return;
}
if (activePipeline) {
activePipeline->deactivate();
}
activePipeline = this;
activateInternal();
}
void Pipeline::activateInternal() {
if (_activeFramebuffer) {
_activeFramebuffer->activate(this);
}
}
void Pipeline::deactivate() {
assert(isActive());
deactivateInternal();
activePipeline = nullptr;
}
void Pipeline::deactivateInternal() {
if (_activeFramebuffer) {
_activeFramebuffer->deactivate();
}
}
Framebuffer *Pipeline::setFramebuffer(Framebuffer *framebuffer) {
Framebuffer *oldFramebuffer = _activeFramebuffer;
if (isActive() && oldFramebuffer) {
oldFramebuffer->deactivate();
}
_activeFramebuffer = framebuffer;
if (isActive() && _activeFramebuffer) {
_activeFramebuffer->activate(this);
}
return oldFramebuffer;
}
} // End of namespace OpenGL

View File

@@ -0,0 +1,167 @@
/* 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.
*
* 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.
*
* 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
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BACKENDS_GRAPHICS_OPENGL_PIPELINES_PIPELINE_H
#define BACKENDS_GRAPHICS_OPENGL_PIPELINES_PIPELINE_H
#include "graphics/opengl/system_headers.h"
#include "graphics/opengl/texture.h"
#include "math/matrix4.h"
namespace OpenGL {
class Framebuffer;
/**
* Interface for OpenGL pipeline functionality.
*
* This encapsulates differences in various rendering pipelines used for
* OpenGL, OpenGL ES 1, and OpenGL ES 2.
*/
class Pipeline {
public:
/**
* Deactivate any pipeline.
*/
static void disable() { if (activePipeline) activePipeline->deactivate(); }
Pipeline();
virtual ~Pipeline() { if (isActive()) deactivate(); }
/**
* Activate the pipeline.
*
* This sets the OpenGL state to make use of drawing with the given
* OpenGL pipeline.
*/
void activate();
/**
* Deactivate the pipeline.
*/
void deactivate();
/**
* Set framebuffer to render to.
*
* Client is responsible for any memory management related to framebuffer.
*
* @param framebuffer Framebuffer to activate.
* @return Formerly active framebuffer.
*/
Framebuffer *setFramebuffer(Framebuffer *framebuffer);
/**
* Set modulation color.
*
* @param r Red component in [0,1].
* @param g Green component in [0,1].
* @param b Blue component in [0,1].
* @param a Alpha component in [0,1].
*/
virtual void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) = 0;
/**
* Draw a texture rectangle to the currently active framebuffer.
*
* @param texture Texture to use for drawing.
* @param coordinates x1, y1, x2, y2 coordinates where to draw the texture.
*/
inline void drawTexture(const Texture &texture, const GLfloat *coordinates, const GLfloat *texcoords) {
drawTextureInternal(texture, coordinates, texcoords);
}
inline void drawTexture(const Texture &texture, const GLfloat *coordinates) {
drawTextureInternal(texture, coordinates, texture.getTexCoords());
}
inline void drawTexture(const Texture &texture, GLfloat x, GLfloat y, GLfloat w, GLfloat h) {
const GLfloat coordinates[4*2] = {
x, y,
x + w, y,
x, y + h,
x + w, y + h
};
drawTextureInternal(texture, coordinates, texture.getTexCoords());
}
inline void drawTexture(const Texture &texture, GLfloat x, GLfloat y, GLfloat w, GLfloat h, const Common::Rect &clip) {
const GLfloat coordinates[4*2] = {
x, y,
x + w, y,
x, y + h,
x + w, y + h
};
const uint tw = texture.getWidth(),
th = texture.getHeight();
if (tw == 0 || th == 0) {
// Nothing to display
return;
}
const GLfloat texcoords[4*2] = {
(float)clip.left / tw, (float)clip.top / th,
(float)clip.right / tw, (float)clip.top / th,
(float)clip.left / tw, (float)clip.bottom / th,
(float)clip.right / tw, (float)clip.bottom / th
};
drawTextureInternal(texture, coordinates, texcoords);
}
/**
* Set the projection matrix.
*
* This is intended to be only ever be used by Framebuffer subclasses.
*/
virtual void setProjectionMatrix(const Math::Matrix4 &projectionMatrix) = 0;
protected:
/**
* Activate the pipeline.
*
* This sets the OpenGL state to make use of drawing with the given
* OpenGL pipeline.
*/
virtual void activateInternal();
/**
* Deactivate the pipeline.
*/
virtual void deactivateInternal();
virtual void drawTextureInternal(const Texture &texture, const GLfloat *coordinates, const GLfloat *texcoords) = 0;
bool isActive() const { return activePipeline == this; }
Framebuffer *_activeFramebuffer;
private:
/** Currently active rendering pipeline. */
static Pipeline *activePipeline;
};
} // End of namespace OpenGL
#endif

View File

@@ -0,0 +1,110 @@
/* 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.
*
* 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.
*
* 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
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "backends/graphics/opengl/pipelines/shader.h"
#include "backends/graphics/opengl/shader.h"
#include "backends/graphics/opengl/framebuffer.h"
#include "graphics/opengl/debug.h"
namespace OpenGL {
// A 4 elements with 2 components vector of floats
static const int kCoordinatesSize = 4 * 2 * sizeof(float);
#if !USE_FORCED_GLES
ShaderPipeline::ShaderPipeline(Shader *shader)
: _activeShader(shader), _colorAttributes(), _colorDirty(true) {
// Use the same VBO for vertices and texcoords as we modify them at the same time
_coordsVBO = OpenGL::Shader::createBuffer(GL_ARRAY_BUFFER, kCoordinatesSize, nullptr, GL_STATIC_DRAW);
_activeShader->enableVertexAttribute("position", _coordsVBO, 2, GL_FLOAT, GL_FALSE, 0, 0);
_texcoordsVBO = OpenGL::Shader::createBuffer(GL_ARRAY_BUFFER, kCoordinatesSize, nullptr, GL_STATIC_DRAW);
_activeShader->enableVertexAttribute("texCoordIn", _texcoordsVBO, 2, GL_FLOAT, GL_FALSE, 0, 0);
_colorVBO = OpenGL::Shader::createBuffer(GL_ARRAY_BUFFER, sizeof(_colorAttributes), nullptr, GL_DYNAMIC_DRAW);
_activeShader->enableVertexAttribute("blendColorIn", _colorVBO, 4, GL_FLOAT, GL_FALSE, 0, 0);
}
ShaderPipeline::~ShaderPipeline() {
delete _activeShader;
OpenGL::Shader::freeBuffer(_coordsVBO);
OpenGL::Shader::freeBuffer(_texcoordsVBO);
OpenGL::Shader::freeBuffer(_colorVBO);
}
void ShaderPipeline::activateInternal() {
Pipeline::activateInternal();
// Disable 3D properties.
GL_CALL(glDisable(GL_CULL_FACE));
GL_CALL(glDisable(GL_DEPTH_TEST));
GL_CALL(glDisable(GL_DITHER));
if (OpenGLContext.multitextureSupported) {
GL_CALL(glActiveTexture(GL_TEXTURE0));
}
_activeShader->use();
}
void ShaderPipeline::deactivateInternal() {
_activeShader->unbind();
Pipeline::deactivateInternal();
}
void ShaderPipeline::setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
GLfloat *dst = _colorAttributes;
for (uint i = 0; i < 4; ++i) {
*dst++ = r;
*dst++ = g;
*dst++ = b;
*dst++ = a;
}
_colorDirty = true;
}
void ShaderPipeline::drawTextureInternal(const Texture &texture, const GLfloat *coordinates, const GLfloat *texcoords) {
assert(isActive());
texture.bind();
if (_colorDirty) {
GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, _colorVBO));
GL_CALL(glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(_colorAttributes), _colorAttributes));
_colorDirty = false;
}
GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, _coordsVBO));
GL_CALL(glBufferData(GL_ARRAY_BUFFER, kCoordinatesSize, coordinates, GL_STATIC_DRAW));
GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, _texcoordsVBO));
GL_CALL(glBufferData(GL_ARRAY_BUFFER, kCoordinatesSize, texcoords, GL_STATIC_DRAW));
GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, 0));
GL_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
}
void ShaderPipeline::setProjectionMatrix(const Math::Matrix4 &projectionMatrix) {
assert(isActive());
_activeShader->setUniform("projection", projectionMatrix);
}
#endif // !USE_FORCED_GLES
} // End of namespace OpenGL

View File

@@ -0,0 +1,59 @@
/* 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.
*
* 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.
*
* 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
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BACKENDS_GRAPHICS_OPENGL_PIPELINES_SHADER_H
#define BACKENDS_GRAPHICS_OPENGL_PIPELINES_SHADER_H
#include "backends/graphics/opengl/pipelines/pipeline.h"
namespace OpenGL {
#if !USE_FORCED_GLES
class Shader;
class ShaderPipeline : public Pipeline {
public:
ShaderPipeline(Shader *shader);
~ShaderPipeline() override;
void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) override;
void setProjectionMatrix(const Math::Matrix4 &projectionMatrix) override;
protected:
void activateInternal() override;
void deactivateInternal() override;
void drawTextureInternal(const Texture &texture, const GLfloat *coordinates, const GLfloat *texcoords) override;
GLuint _coordsVBO;
GLuint _texcoordsVBO;
GLuint _colorVBO;
GLfloat _colorAttributes[4*4];
bool _colorDirty;
Shader *const _activeShader;
};
#endif // !USE_FORCED_GLES
} // End of namespace OpenGL
#endif