2021-04-18 16:40:46 +02: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.
|
|
|
|
*
|
2022-10-06 18:58:18 +02: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.
|
2021-04-18 16:40:46 +02: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
|
2022-10-06 18:58:18 +02:00
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2021-04-18 16:40:46 +02:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef BACKENDS_GRAPHICS_OPENGL_PIPELINES_LIBRETRO_H
|
|
|
|
#define BACKENDS_GRAPHICS_OPENGL_PIPELINES_LIBRETRO_H
|
|
|
|
|
2022-06-29 22:56:28 +01:00
|
|
|
#include "graphics/opengl/system_headers.h"
|
2021-04-18 16:40:46 +02:00
|
|
|
|
|
|
|
#if !USE_FORCED_GLES
|
|
|
|
#include "backends/graphics/opengl/pipelines/shader.h"
|
|
|
|
|
|
|
|
#include "common/array.h"
|
2022-06-30 20:59:23 +01:00
|
|
|
#include "common/fs.h"
|
2021-04-18 16:40:46 +02:00
|
|
|
|
|
|
|
namespace Graphics {
|
|
|
|
struct Surface;
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace OpenGL {
|
|
|
|
|
|
|
|
namespace LibRetro {
|
|
|
|
struct ShaderPreset;
|
|
|
|
struct ShaderPass;
|
|
|
|
} // End of namespace LibRetro
|
|
|
|
|
|
|
|
class TextureTarget;
|
2022-11-01 08:48:25 +01:00
|
|
|
class LibRetroTextureTarget;
|
2021-04-18 16:40:46 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Pipeline implementation using Libretro shader presets.
|
|
|
|
*/
|
2022-11-01 08:48:25 +01:00
|
|
|
class LibRetroPipeline : public Pipeline {
|
2021-04-18 16:40:46 +02:00
|
|
|
public:
|
2022-06-30 20:59:23 +01:00
|
|
|
LibRetroPipeline();
|
|
|
|
LibRetroPipeline(const Common::FSNode &shaderPreset);
|
2022-10-31 11:49:38 +01:00
|
|
|
~LibRetroPipeline() override;
|
2021-04-18 16:40:46 +02:00
|
|
|
|
2022-11-01 08:48:25 +01:00
|
|
|
void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) override;
|
2022-10-31 11:49:38 +01:00
|
|
|
void setProjectionMatrix(const Math::Matrix4 &projectionMatrix) override;
|
2021-04-18 16:40:46 +02:00
|
|
|
|
2022-06-30 20:59:23 +01:00
|
|
|
bool open(const Common::FSNode &shaderPreset);
|
|
|
|
void close();
|
|
|
|
|
2022-11-01 08:48:25 +01:00
|
|
|
/* Called by OpenGLGraphicsManager */
|
|
|
|
void enableLinearFiltering(bool enabled) { _linearFiltering = enabled; }
|
|
|
|
/* 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();
|
2022-10-21 08:34:28 +02:00
|
|
|
bool isAnimated() const { return _isAnimated; }
|
2022-06-30 21:13:00 +01:00
|
|
|
|
|
|
|
static bool isSupportedByContext() {
|
|
|
|
return OpenGLContext.shadersSupported
|
2022-09-30 09:07:49 +02:00
|
|
|
&& OpenGLContext.multitextureSupported
|
|
|
|
&& OpenGLContext.framebufferObjectSupported;
|
2022-06-30 21:13:00 +01:00
|
|
|
}
|
2021-04-18 16:40:46 +02:00
|
|
|
private:
|
2022-10-31 11:49:38 +01:00
|
|
|
void activateInternal() override;
|
|
|
|
void deactivateInternal() override;
|
2022-11-04 07:41:21 +01:00
|
|
|
void drawTextureInternal(const GLTexture &texture, const GLfloat *coordinates, const GLfloat *texcoords) override;
|
2021-04-18 16:40:46 +02:00
|
|
|
|
2022-06-30 20:59:23 +01:00
|
|
|
bool loadTextures();
|
|
|
|
bool loadPasses();
|
2021-04-18 16:40:46 +02:00
|
|
|
|
|
|
|
void setPipelineState();
|
2022-10-08 22:56:22 +02:00
|
|
|
bool setupFBOs();
|
2021-04-18 16:40:46 +02:00
|
|
|
void setupPassUniforms(const uint id);
|
|
|
|
void setShaderTexUniforms(const Common::String &prefix, Shader *shader, const GLTexture &texture);
|
|
|
|
|
2022-11-01 08:48:25 +01:00
|
|
|
/* Pipelines used to draw all layers
|
|
|
|
* First before the scaler then after it to draw on screen
|
|
|
|
*/
|
|
|
|
ShaderPipeline _inputPipeline;
|
|
|
|
ShaderPipeline _outputPipeline;
|
|
|
|
bool _needsScaling;
|
2021-04-18 16:40:46 +02:00
|
|
|
|
2022-11-01 08:48:25 +01:00
|
|
|
const LibRetro::ShaderPreset *_shaderPreset;
|
2021-04-18 16:40:46 +02:00
|
|
|
|
|
|
|
uint _inputWidth;
|
|
|
|
uint _inputHeight;
|
2022-11-01 08:48:25 +01:00
|
|
|
Common::Rect _outputRect;
|
2021-04-18 16:40:46 +02:00
|
|
|
|
2022-11-01 08:48:25 +01:00
|
|
|
bool _linearFiltering;
|
2021-04-18 16:40:46 +02:00
|
|
|
|
2022-10-21 08:34:28 +02:00
|
|
|
/* Determines if preset depends on frameCount or from previous frames */
|
|
|
|
bool _isAnimated;
|
2022-10-16 19:00:35 +02:00
|
|
|
uint _frameCount;
|
|
|
|
|
2022-11-01 08:48:25 +01:00
|
|
|
LibRetroTextureTarget *_inputTarget;
|
|
|
|
|
2021-04-18 16:40:46 +02:00
|
|
|
struct Texture {
|
|
|
|
Texture() : textureData(nullptr), glTexture(nullptr) {}
|
|
|
|
Texture(Graphics::Surface *tD, GLTexture *glTex) : textureData(tD), glTexture(glTex) {}
|
|
|
|
|
|
|
|
Common::String id;
|
|
|
|
Graphics::Surface *textureData;
|
|
|
|
GLTexture *glTexture;
|
|
|
|
};
|
2022-06-30 20:59:23 +01:00
|
|
|
Texture loadTexture(const Common::FSNode &fileNode);
|
2021-04-18 16:40:46 +02:00
|
|
|
|
|
|
|
typedef Common::Array<Texture> TextureArray;
|
|
|
|
TextureArray _textures;
|
|
|
|
|
|
|
|
struct Pass {
|
|
|
|
Pass()
|
2022-09-30 09:07:49 +02:00
|
|
|
: shaderPass(nullptr), shader(nullptr), target(nullptr),
|
2022-10-16 19:00:35 +02:00
|
|
|
texCoords(), texSamplers(), inputTexture(nullptr), vertexCoord(), hasFrameCount(false) {}
|
2021-04-18 16:40:46 +02:00
|
|
|
Pass(const LibRetro::ShaderPass *sP, Shader *s, TextureTarget *t)
|
2022-09-30 09:07:49 +02:00
|
|
|
: shaderPass(sP), shader(s), target(t), texCoords(),
|
2022-10-16 19:00:35 +02:00
|
|
|
texSamplers(), inputTexture(nullptr), vertexCoord(), hasFrameCount(false) {}
|
2021-04-18 16:40:46 +02:00
|
|
|
|
|
|
|
const LibRetro::ShaderPass *shaderPass;
|
|
|
|
Shader *shader;
|
|
|
|
TextureTarget *target;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Description of texture coordinates bound to attribute.
|
|
|
|
*/
|
|
|
|
struct TexCoordAttribute {
|
|
|
|
/**
|
2022-06-29 22:56:28 +01:00
|
|
|
* Attribute name to bind data to.
|
2021-04-18 16:40:46 +02:00
|
|
|
*/
|
2022-06-29 22:56:28 +01:00
|
|
|
Common::String name;
|
2021-04-18 16:40:46 +02:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
2022-06-29 22:56:28 +01:00
|
|
|
TexCoordAttribute() : name(), type(), index() {}
|
|
|
|
TexCoordAttribute(const Common::String &n, Type t, uint i) : name(n), type(t), index(i) {}
|
2021-04-18 16:40:46 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
typedef Common::Array<TexCoordAttribute> TexCoordAttributeArray;
|
|
|
|
TexCoordAttributeArray texCoords;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Build the 'texCoords' array.
|
|
|
|
*
|
|
|
|
* @param id Identifier of the current pass.
|
|
|
|
*/
|
2022-10-16 13:21:08 +02:00
|
|
|
void buildTexCoords(const uint id, const Common::StringArray &aliases);
|
2021-04-18 16:40:46 +02:00
|
|
|
|
|
|
|
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.
|
|
|
|
*/
|
2022-10-16 13:21:08 +02:00
|
|
|
void buildTexSamplers(const uint id, const TextureArray &textures, const Common::StringArray &aliases);
|
2021-04-18 16:40:46 +02:00
|
|
|
|
2022-06-29 22:56:28 +01:00
|
|
|
void addTexSampler(const Common::String &name, uint *unit, const TextureSampler::Type type, const uint index, const bool prefixIsId = false);
|
2021-04-18 16:40:46 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Input texture of the pass.
|
|
|
|
*/
|
|
|
|
const GLTexture *inputTexture;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Vertex coordinates used for drawing.
|
|
|
|
*/
|
|
|
|
GLfloat vertexCoord[2*4];
|
2022-10-16 19:00:35 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Whether the shader has a FrameCount uniform or not
|
|
|
|
* Allows to speed up if it is not here
|
|
|
|
*/
|
|
|
|
bool hasFrameCount;
|
2021-04-18 16:40:46 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
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
|