2007-11-27 19:40:25 +00:00
|
|
|
/********************************************************************
|
2007-04-29 17:35:43 +00:00
|
|
|
KWin - the KDE window manager
|
|
|
|
This file is part of the KDE project.
|
|
|
|
|
|
|
|
Copyright (C) 2006-2007 Rivo Laks <rivolaks@hot.ee>
|
2011-03-16 18:39:10 +00:00
|
|
|
Copyright (C) 2010, 2011 Martin Gräßlin <mgraesslin@kde.org>
|
2007-04-29 17:35:43 +00:00
|
|
|
|
2007-11-27 19:40:25 +00: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 2 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/>.
|
|
|
|
*********************************************************************/
|
2007-04-29 17:35:43 +00:00
|
|
|
|
|
|
|
#ifndef KWIN_GLUTILS_H
|
|
|
|
#define KWIN_GLUTILS_H
|
|
|
|
|
2013-02-26 07:02:27 +00:00
|
|
|
// kwin
|
2013-12-03 09:43:57 +00:00
|
|
|
#include <kwinglutils_export.h>
|
2013-02-26 07:02:27 +00:00
|
|
|
#include "kwinglutils_funcs.h"
|
|
|
|
#include "kwingltexture.h"
|
2007-04-29 17:35:43 +00:00
|
|
|
|
2013-02-26 07:02:27 +00:00
|
|
|
// Qt
|
2013-02-26 08:00:51 +00:00
|
|
|
#include <QSize>
|
|
|
|
#include <QStack>
|
2007-04-29 17:35:43 +00:00
|
|
|
|
2008-01-16 18:13:24 +00:00
|
|
|
/** @addtogroup kwineffects */
|
|
|
|
/** @{ */
|
2007-04-29 17:35:43 +00:00
|
|
|
|
2010-11-14 19:49:00 +00:00
|
|
|
class QVector2D;
|
|
|
|
class QVector3D;
|
|
|
|
class QVector4D;
|
2010-12-04 11:25:49 +00:00
|
|
|
class QMatrix4x4;
|
2007-04-29 17:35:43 +00:00
|
|
|
|
|
|
|
template< class K, class V > class QHash;
|
|
|
|
|
|
|
|
|
|
|
|
namespace KWin
|
|
|
|
{
|
|
|
|
|
2010-07-19 20:53:32 +00:00
|
|
|
class GLVertexBuffer;
|
|
|
|
class GLVertexBufferPrivate;
|
2007-07-04 20:33:35 +00:00
|
|
|
|
2007-04-29 17:35:43 +00:00
|
|
|
// Initializes OpenGL stuff. This includes resolving function pointers as
|
|
|
|
// well as checking for GL version and extensions
|
|
|
|
// Note that GL context has to be created by the time this function is called
|
2016-11-11 08:16:23 +00:00
|
|
|
typedef void (*resolveFuncPtr)();
|
|
|
|
void KWINGLUTILS_EXPORT initGL(std::function<resolveFuncPtr(const char*)> resolveFunction);
|
2011-04-27 12:51:36 +00:00
|
|
|
// Cleans up all resources hold by the GL Context
|
2013-12-03 09:43:57 +00:00
|
|
|
void KWINGLUTILS_EXPORT cleanupGL();
|
2007-04-29 17:35:43 +00:00
|
|
|
|
|
|
|
|
2013-12-03 09:43:57 +00:00
|
|
|
bool KWINGLUTILS_EXPORT hasGLVersion(int major, int minor, int release = 0);
|
2007-04-29 17:35:43 +00:00
|
|
|
// use for both OpenGL and GLX extensions
|
2014-02-11 18:35:54 +00:00
|
|
|
bool KWINGLUTILS_EXPORT hasGLExtension(const QByteArray &extension);
|
2007-04-29 17:35:43 +00:00
|
|
|
|
|
|
|
// detect OpenGL error (add to various places in code to pinpoint the place)
|
2013-12-03 09:43:57 +00:00
|
|
|
bool KWINGLUTILS_EXPORT checkGLError(const char* txt);
|
2007-04-29 17:35:43 +00:00
|
|
|
|
2016-08-10 06:25:20 +00:00
|
|
|
QList<QByteArray> KWINGLUTILS_EXPORT openGLExtensions();
|
|
|
|
|
2013-12-03 09:43:57 +00:00
|
|
|
class KWINGLUTILS_EXPORT GLShader
|
2011-01-30 14:34:42 +00:00
|
|
|
{
|
|
|
|
public:
|
2012-07-22 13:44:47 +00:00
|
|
|
enum Flags {
|
|
|
|
NoFlags = 0,
|
|
|
|
ExplicitLinking = (1 << 0)
|
|
|
|
};
|
|
|
|
|
|
|
|
GLShader(const QString &vertexfile, const QString &fragmentfile, unsigned int flags = NoFlags);
|
2011-01-30 14:34:42 +00:00
|
|
|
~GLShader();
|
|
|
|
|
|
|
|
bool isValid() const {
|
|
|
|
return mValid;
|
|
|
|
}
|
|
|
|
|
2012-07-22 13:44:47 +00:00
|
|
|
void bindAttributeLocation(const char *name, int index);
|
|
|
|
void bindFragDataLocation(const char *name, int index);
|
|
|
|
|
|
|
|
bool link();
|
|
|
|
|
2011-01-30 14:34:42 +00:00
|
|
|
int uniformLocation(const char* name);
|
2011-02-04 18:57:19 +00:00
|
|
|
|
2011-01-30 14:34:42 +00:00
|
|
|
bool setUniform(const char* name, float value);
|
|
|
|
bool setUniform(const char* name, int value);
|
|
|
|
bool setUniform(const char* name, const QVector2D& value);
|
|
|
|
bool setUniform(const char* name, const QVector3D& value);
|
|
|
|
bool setUniform(const char* name, const QVector4D& value);
|
|
|
|
bool setUniform(const char* name, const QMatrix4x4& value);
|
|
|
|
bool setUniform(const char* name, const QColor& color);
|
2011-02-04 18:57:19 +00:00
|
|
|
|
|
|
|
bool setUniform(int location, float value);
|
|
|
|
bool setUniform(int location, int value);
|
|
|
|
bool setUniform(int location, const QVector2D &value);
|
|
|
|
bool setUniform(int location, const QVector3D &value);
|
|
|
|
bool setUniform(int location, const QVector4D &value);
|
|
|
|
bool setUniform(int location, const QMatrix4x4 &value);
|
|
|
|
bool setUniform(int location, const QColor &value);
|
|
|
|
|
2011-01-30 14:34:42 +00:00
|
|
|
int attributeLocation(const char* name);
|
|
|
|
bool setAttribute(const char* name, float value);
|
|
|
|
/**
|
|
|
|
* @return The value of the uniform as a matrix
|
|
|
|
* @since 4.7
|
|
|
|
**/
|
|
|
|
QMatrix4x4 getUniformMatrix4x4(const char* name);
|
|
|
|
|
2011-02-10 18:16:04 +00:00
|
|
|
enum MatrixUniform {
|
|
|
|
TextureMatrix = 0,
|
|
|
|
ProjectionMatrix,
|
|
|
|
ModelViewMatrix,
|
2014-04-01 16:07:47 +00:00
|
|
|
ModelViewProjectionMatrix,
|
2011-02-10 18:16:04 +00:00
|
|
|
WindowTransformation,
|
|
|
|
ScreenTransformation,
|
|
|
|
MatrixCount
|
|
|
|
};
|
|
|
|
|
|
|
|
enum Vec2Uniform {
|
|
|
|
Offset,
|
|
|
|
Vec2UniformCount
|
|
|
|
};
|
|
|
|
|
2011-02-12 00:36:21 +00:00
|
|
|
enum Vec4Uniform {
|
|
|
|
ModulationConstant,
|
|
|
|
Vec4UniformCount
|
|
|
|
};
|
|
|
|
|
2011-02-10 18:16:04 +00:00
|
|
|
enum FloatUniform {
|
|
|
|
Saturation,
|
|
|
|
FloatUniformCount
|
|
|
|
};
|
|
|
|
|
|
|
|
enum IntUniform {
|
2012-10-28 10:34:02 +00:00
|
|
|
AlphaToOne, ///< @deprecated no longer used
|
2011-02-10 18:16:04 +00:00
|
|
|
IntUniformCount
|
|
|
|
};
|
|
|
|
|
2013-03-20 19:06:18 +00:00
|
|
|
enum ColorUniform {
|
|
|
|
Color,
|
|
|
|
ColorUniformCount
|
|
|
|
};
|
|
|
|
|
2011-02-10 18:16:04 +00:00
|
|
|
bool setUniform(MatrixUniform uniform, const QMatrix4x4 &matrix);
|
|
|
|
bool setUniform(Vec2Uniform uniform, const QVector2D &value);
|
2011-02-12 00:36:21 +00:00
|
|
|
bool setUniform(Vec4Uniform uniform, const QVector4D &value);
|
2011-02-10 18:16:04 +00:00
|
|
|
bool setUniform(FloatUniform uniform, float value);
|
|
|
|
bool setUniform(IntUniform uniform, int value);
|
2013-03-20 19:06:18 +00:00
|
|
|
bool setUniform(ColorUniform uniform, const QVector4D &value);
|
|
|
|
bool setUniform(ColorUniform uniform, const QColor &value);
|
2011-02-10 18:16:04 +00:00
|
|
|
|
2011-01-30 14:34:42 +00:00
|
|
|
protected:
|
2012-07-22 13:44:47 +00:00
|
|
|
GLShader(unsigned int flags = NoFlags);
|
2011-01-30 14:34:42 +00:00
|
|
|
bool loadFromFiles(const QString& vertexfile, const QString& fragmentfile);
|
2011-02-04 15:41:55 +00:00
|
|
|
bool load(const QByteArray &vertexSource, const QByteArray &fragmentSource);
|
2012-11-13 20:41:02 +00:00
|
|
|
const QByteArray prepareSource(GLenum shaderType, const QByteArray &sourceCode) const;
|
2011-02-04 16:03:56 +00:00
|
|
|
bool compile(GLuint program, GLenum shaderType, const QByteArray &sourceCode) const;
|
2011-01-30 14:34:42 +00:00
|
|
|
void bind();
|
|
|
|
void unbind();
|
2011-02-10 18:16:04 +00:00
|
|
|
void resolveLocations();
|
2011-01-30 14:34:42 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
unsigned int mProgram;
|
2011-02-10 18:16:04 +00:00
|
|
|
bool mValid:1;
|
|
|
|
bool mLocationsResolved:1;
|
2012-07-22 13:44:47 +00:00
|
|
|
bool mExplicitLinking:1;
|
2011-02-10 18:16:04 +00:00
|
|
|
int mMatrixLocation[MatrixCount];
|
|
|
|
int mVec2Location[Vec2UniformCount];
|
2011-02-12 00:36:21 +00:00
|
|
|
int mVec4Location[Vec4UniformCount];
|
2011-02-10 18:16:04 +00:00
|
|
|
int mFloatLocation[FloatUniformCount];
|
|
|
|
int mIntLocation[IntUniformCount];
|
2013-03-20 19:06:18 +00:00
|
|
|
int mColorLocation[ColorUniformCount];
|
2011-02-10 18:16:04 +00:00
|
|
|
|
2011-01-30 14:34:42 +00:00
|
|
|
friend class ShaderManager;
|
|
|
|
};
|
2007-04-29 17:35:43 +00:00
|
|
|
|
2014-04-01 16:07:23 +00:00
|
|
|
|
|
|
|
enum class ShaderTrait {
|
|
|
|
MapTexture = (1 << 0),
|
|
|
|
UniformColor = (1 << 1),
|
|
|
|
Modulate = (1 << 2),
|
|
|
|
AdjustSaturation = (1 << 3),
|
|
|
|
};
|
|
|
|
|
|
|
|
Q_DECLARE_FLAGS(ShaderTraits, ShaderTrait)
|
|
|
|
|
|
|
|
|
2010-12-11 09:25:46 +00:00
|
|
|
/**
|
|
|
|
* @short Manager for Shaders.
|
|
|
|
*
|
|
|
|
* This class provides some built-in shaders to be used by both compositing scene and effects.
|
|
|
|
* The ShaderManager provides methods to bind a built-in or a custom shader and keeps track of
|
|
|
|
* the shaders which have been bound. When a shader is unbound the previously bound shader
|
|
|
|
* will be rebound.
|
|
|
|
*
|
2013-03-12 12:17:53 +00:00
|
|
|
* @author Martin Gräßlin <mgraesslin@kde.org>
|
2010-12-11 09:25:46 +00:00
|
|
|
* @since 4.7
|
|
|
|
**/
|
2013-12-03 09:43:57 +00:00
|
|
|
class KWINGLUTILS_EXPORT ShaderManager
|
2010-12-11 09:25:46 +00:00
|
|
|
{
|
2011-01-30 14:34:42 +00:00
|
|
|
public:
|
2014-04-01 16:07:23 +00:00
|
|
|
/**
|
|
|
|
* Returns a shader with the given traits, creating it if necessary.
|
|
|
|
*/
|
|
|
|
GLShader *shader(ShaderTraits traits);
|
|
|
|
|
2011-01-30 14:34:42 +00:00
|
|
|
/**
|
|
|
|
* @return The currently bound shader or @c null if no shader is bound.
|
|
|
|
**/
|
|
|
|
GLShader *getBoundShader() const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return @c true if a shader is bound, @c false otherwise
|
|
|
|
**/
|
|
|
|
bool isShaderBound() const;
|
2011-07-23 16:57:50 +00:00
|
|
|
/**
|
|
|
|
* Is @c true if the environment variable KWIN_GL_DEBUG is set to 1.
|
|
|
|
* In that case shaders are compiled with KWIN_SHADER_DEBUG defined.
|
|
|
|
* @returns @c true if shaders are compiled with debug information
|
|
|
|
* @since 4.8
|
|
|
|
**/
|
|
|
|
bool isShaderDebug() const;
|
2011-01-30 14:34:42 +00:00
|
|
|
|
2014-04-01 16:07:23 +00:00
|
|
|
/**
|
|
|
|
* Pushes the current shader onto the stack and binds a shader
|
|
|
|
* with the given traits.
|
|
|
|
*/
|
|
|
|
GLShader *pushShader(ShaderTraits traits);
|
|
|
|
|
2011-01-30 14:34:42 +00:00
|
|
|
/**
|
|
|
|
* Binds the @p shader.
|
|
|
|
* To unbind the shader use @link popShader. A previous bound shader will be rebound.
|
|
|
|
* To bind a built-in shader use the more specific method.
|
|
|
|
* @param shader The shader to be bound
|
|
|
|
* @see popShader
|
|
|
|
**/
|
|
|
|
void pushShader(GLShader *shader);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Unbinds the currently bound shader and rebinds a previous stored shader.
|
|
|
|
* If there is no previous shader, no shader will be rebound.
|
|
|
|
* It is not safe to call this method if there is no bound shader.
|
|
|
|
* @see pushShader
|
|
|
|
* @see getBoundShader
|
|
|
|
**/
|
|
|
|
void popShader();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates a GLShader with the specified sources.
|
|
|
|
* The difference to GLShader is that it does not need to be loaded from files.
|
|
|
|
* @param vertexSource The source code of the vertex shader
|
|
|
|
* @param fragmentSource The source code of the fragment shader.
|
|
|
|
* @return The created shader
|
|
|
|
**/
|
2011-02-04 15:41:55 +00:00
|
|
|
GLShader *loadShaderFromCode(const QByteArray &vertexSource, const QByteArray &fragmentSource);
|
2011-01-30 14:34:42 +00:00
|
|
|
|
2015-11-27 14:37:08 +00:00
|
|
|
/**
|
|
|
|
* Creates a custom shader with the given @p traits and custom @p vertexSource and or @p fragmentSource.
|
|
|
|
* If the @p vertexSource is empty a vertex shader with the given @p traits is generated.
|
|
|
|
* If it is not empty the @p vertexSource is used as the source for the vertex shader.
|
|
|
|
*
|
|
|
|
* The same applies for argument @p fragmentSource just for the fragment shader.
|
|
|
|
*
|
|
|
|
* So if both @p vertesSource and @p fragmentSource are provided the @p traits are ignored.
|
|
|
|
* If neither are provided a new shader following the @p traits is generated.
|
|
|
|
*
|
|
|
|
* @param traits The shader traits for generating the shader
|
|
|
|
* @param vertesSource optional vertex shader source code to be used instead of shader traits
|
|
|
|
* @param fragmentSource optional fragment shader source code to be used instead of shader traits
|
|
|
|
* @return new generated shader
|
|
|
|
* @since 5.6
|
|
|
|
**/
|
|
|
|
GLShader *generateCustomShader(ShaderTraits traits, const QByteArray &vertexSource = QByteArray(), const QByteArray &fragmentSource = QByteArray());
|
|
|
|
|
2016-01-26 14:38:42 +00:00
|
|
|
/**
|
|
|
|
* Creates a custom shader with the given @p traits and custom @p vertexFile and or @p fragmentFile.
|
|
|
|
* The file names specified in @p vertexFile and @p fragmentFile are relative paths to the shaders
|
|
|
|
* resource file shipped together with KWin. This means this method can only be used for built-in
|
|
|
|
* effects, for 3rd party effects @link {generateCustomShader} should be used.
|
|
|
|
*
|
|
|
|
* If the @p vertexFile is empty a vertex shader with the given @p traits is generated.
|
|
|
|
* If it is not empty the @p vertexFile is used as the source for the vertex shader.
|
|
|
|
*
|
|
|
|
* The same applies for argument @p fragmentFile just for the fragment shader.
|
|
|
|
*
|
|
|
|
* So if both @p vertexFile and @p fragmentFile are provided the @p traits are ignored.
|
|
|
|
* If neither are provided a new shader following the @p traits is generated.
|
|
|
|
*
|
|
|
|
* @param traits The shader traits for generating the shader
|
|
|
|
* @param vertexFile optional vertex shader source code to be used instead of shader traits
|
|
|
|
* @param fragmentFile optional fragment shader source code to be used instead of shader traits
|
|
|
|
* @return new generated shader
|
|
|
|
* @see generateCustomShader
|
|
|
|
* @since 5.6
|
|
|
|
**/
|
|
|
|
GLShader *generateShaderFromResources(ShaderTraits traits, const QString &vertexFile = QString(), const QString &fragmentFile = QString());
|
|
|
|
|
2014-11-15 11:59:12 +00:00
|
|
|
/**
|
|
|
|
* Compiles and tests the dynamically generated shaders.
|
|
|
|
* Returns true if successful and false otherwise.
|
|
|
|
*/
|
|
|
|
bool selfTest();
|
|
|
|
|
2011-01-30 14:34:42 +00:00
|
|
|
/**
|
|
|
|
* @return a pointer to the ShaderManager instance
|
|
|
|
**/
|
|
|
|
static ShaderManager *instance();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @internal
|
|
|
|
**/
|
|
|
|
static void cleanup();
|
|
|
|
|
|
|
|
private:
|
|
|
|
ShaderManager();
|
|
|
|
~ShaderManager();
|
|
|
|
|
2013-03-13 16:38:35 +00:00
|
|
|
void bindFragDataLocations(GLShader *shader);
|
2012-09-21 17:04:26 +00:00
|
|
|
void bindAttributeLocations(GLShader *shader) const;
|
2011-01-30 14:34:42 +00:00
|
|
|
|
2014-04-01 16:07:23 +00:00
|
|
|
QByteArray generateVertexSource(ShaderTraits traits) const;
|
|
|
|
QByteArray generateFragmentSource(ShaderTraits traits) const;
|
|
|
|
GLShader *generateShader(ShaderTraits traits);
|
|
|
|
|
2011-01-30 14:34:42 +00:00
|
|
|
QStack<GLShader*> m_boundShaders;
|
2014-04-01 16:07:23 +00:00
|
|
|
QHash<ShaderTraits, GLShader *> m_shaderHash;
|
2011-07-23 16:57:50 +00:00
|
|
|
bool m_debug;
|
2016-01-26 14:38:42 +00:00
|
|
|
QString m_resourcePath;
|
2011-01-30 14:34:42 +00:00
|
|
|
static ShaderManager *s_shaderManager;
|
2010-12-11 09:25:46 +00:00
|
|
|
};
|
|
|
|
|
2012-09-21 09:25:08 +00:00
|
|
|
/**
|
|
|
|
* An helper class to push a Shader on to ShaderManager's stack and ensuring that the Shader
|
|
|
|
* gets popped again from the stack automatically once the object goes out of life.
|
|
|
|
*
|
|
|
|
* How to use:
|
|
|
|
* @code
|
|
|
|
* {
|
|
|
|
* GLShader *myCustomShaderIWantToPush;
|
|
|
|
* ShaderBinder binder(myCustomShaderIWantToPush);
|
|
|
|
* // do stuff with the shader being pushed on the stack
|
|
|
|
* }
|
|
|
|
* // here the Shader is automatically popped as helper does no longer exist.
|
|
|
|
* @endcode
|
|
|
|
*
|
|
|
|
* @since 4.10
|
|
|
|
**/
|
2013-12-03 09:43:57 +00:00
|
|
|
class KWINGLUTILS_EXPORT ShaderBinder
|
2012-09-21 09:25:08 +00:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
/**
|
|
|
|
* @brief Pushes the given @p shader to the ShaderManager's stack.
|
|
|
|
*
|
|
|
|
* @param shader The Shader to push on the stack
|
|
|
|
* @see ShaderManager::pushShader
|
|
|
|
**/
|
2012-12-29 06:34:38 +00:00
|
|
|
explicit ShaderBinder(GLShader *shader);
|
2015-11-26 08:36:54 +00:00
|
|
|
/**
|
|
|
|
* @brief Pushes the Shader with the given @p traits to the ShaderManager's stack.
|
|
|
|
*
|
|
|
|
* @param traits The traits describing the shader
|
|
|
|
* @see ShaderManager::pushShader
|
|
|
|
* @since 5.6
|
|
|
|
**/
|
|
|
|
explicit ShaderBinder(ShaderTraits traits);
|
2012-09-21 09:25:08 +00:00
|
|
|
~ShaderBinder();
|
|
|
|
|
|
|
|
/**
|
2014-02-25 10:02:32 +00:00
|
|
|
* @return The Shader pushed to the Stack.
|
2012-09-21 09:25:08 +00:00
|
|
|
**/
|
|
|
|
GLShader *shader();
|
|
|
|
|
|
|
|
private:
|
|
|
|
GLShader *m_shader;
|
|
|
|
};
|
|
|
|
|
|
|
|
inline
|
|
|
|
ShaderBinder::ShaderBinder(GLShader *shader)
|
|
|
|
: m_shader(shader)
|
|
|
|
{
|
|
|
|
ShaderManager::instance()->pushShader(shader);
|
|
|
|
}
|
|
|
|
|
2015-11-26 08:36:54 +00:00
|
|
|
inline
|
|
|
|
ShaderBinder::ShaderBinder(ShaderTraits traits)
|
|
|
|
: m_shader(nullptr)
|
|
|
|
{
|
|
|
|
m_shader = ShaderManager::instance()->pushShader(traits);
|
|
|
|
}
|
|
|
|
|
2012-09-21 09:25:08 +00:00
|
|
|
inline
|
|
|
|
ShaderBinder::~ShaderBinder()
|
|
|
|
{
|
|
|
|
ShaderManager::instance()->popShader();
|
|
|
|
}
|
|
|
|
|
|
|
|
inline
|
|
|
|
GLShader* ShaderBinder::shader()
|
|
|
|
{
|
|
|
|
return m_shader;
|
|
|
|
}
|
|
|
|
|
2007-04-29 17:35:43 +00:00
|
|
|
/**
|
|
|
|
* @short Render target object
|
|
|
|
*
|
|
|
|
* Render target object enables you to render onto a texture. This texture can
|
|
|
|
* later be used to e.g. do post-processing of the scene.
|
|
|
|
*
|
|
|
|
* @author Rivo Laks <rivolaks@hot.ee>
|
|
|
|
**/
|
2013-12-03 09:43:57 +00:00
|
|
|
class KWINGLUTILS_EXPORT GLRenderTarget
|
2007-04-29 17:35:43 +00:00
|
|
|
{
|
2011-01-30 14:34:42 +00:00
|
|
|
public:
|
|
|
|
/**
|
|
|
|
* Constructs a GLRenderTarget
|
|
|
|
* @param color texture where the scene will be rendered onto
|
|
|
|
**/
|
2012-12-29 06:34:38 +00:00
|
|
|
explicit GLRenderTarget(const GLTexture& color);
|
2011-01-30 14:34:42 +00:00
|
|
|
~GLRenderTarget();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Enables this render target.
|
|
|
|
* All OpenGL commands from now on affect this render target until the
|
|
|
|
* @ref disable method is called
|
|
|
|
**/
|
|
|
|
bool enable();
|
|
|
|
/**
|
|
|
|
* Disables this render target, activating whichever target was active
|
|
|
|
* when @ref enable was called.
|
|
|
|
**/
|
|
|
|
bool disable();
|
|
|
|
|
2011-07-17 15:57:30 +00:00
|
|
|
/**
|
|
|
|
* Sets the target texture
|
|
|
|
* @param target texture where the scene will be rendered on
|
|
|
|
* @since 4.8
|
|
|
|
**/
|
|
|
|
void attachTexture(const GLTexture& target);
|
|
|
|
|
2011-01-30 14:34:42 +00:00
|
|
|
bool valid() const {
|
|
|
|
return mValid;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void initStatic();
|
|
|
|
static bool supported() {
|
2011-02-04 16:30:36 +00:00
|
|
|
return sSupported;
|
2011-01-30 14:34:42 +00:00
|
|
|
}
|
2011-03-13 13:34:30 +00:00
|
|
|
static void pushRenderTarget(GLRenderTarget *target);
|
|
|
|
static GLRenderTarget *popRenderTarget();
|
|
|
|
static bool isRenderTargetBound();
|
2011-08-17 17:32:36 +00:00
|
|
|
/**
|
|
|
|
* Whether the GL_EXT_framebuffer_blit extension is supported.
|
|
|
|
* This functionality is not available in OpenGL ES 2.0.
|
|
|
|
*
|
|
|
|
* @returns whether framebuffer blitting is supported.
|
|
|
|
* @since 4.8
|
|
|
|
**/
|
|
|
|
static bool blitSupported();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Blits the content of the current draw framebuffer into the texture attached to this FBO.
|
|
|
|
*
|
|
|
|
* Be aware that framebuffer blitting may not be supported on all hardware. Use @link blitSupported to check whether
|
|
|
|
* it is supported.
|
|
|
|
* @param source Geometry in screen coordinates which should be blitted, if not specified complete framebuffer is used
|
|
|
|
* @param destination Geometry in attached texture, if not specified complete texture is used as destination
|
|
|
|
* @param filter The filter to use if blitted content needs to be scaled.
|
|
|
|
* @see blitSupported
|
|
|
|
* @since 4.8
|
|
|
|
**/
|
|
|
|
void blitFromFramebuffer(const QRect &source = QRect(), const QRect &destination = QRect(), GLenum filter = GL_LINEAR);
|
2011-01-30 14:34:42 +00:00
|
|
|
|
2014-11-25 07:40:23 +00:00
|
|
|
/**
|
|
|
|
* Sets the virtual screen size to @p s.
|
|
|
|
* @since 5.2
|
|
|
|
**/
|
|
|
|
static void setVirtualScreenSize(const QSize &s) {
|
|
|
|
s_virtualScreenSize = s;
|
|
|
|
}
|
|
|
|
|
2016-10-14 13:29:50 +00:00
|
|
|
/**
|
|
|
|
* Sets the virtual screen geometry to @p g.
|
|
|
|
* This is the geometry of the OpenGL window currently being rendered to
|
|
|
|
* in the virtual geometry space the rendering geometries use.
|
2016-10-18 14:22:57 +00:00
|
|
|
* @see virtualScreenGeometry
|
2016-10-14 13:29:50 +00:00
|
|
|
* @since 5.9
|
|
|
|
**/
|
|
|
|
static void setVirtualScreenGeometry(const QRect &g) {
|
|
|
|
s_virtualScreenGeometry = g;
|
|
|
|
}
|
|
|
|
|
2016-10-18 14:22:57 +00:00
|
|
|
/**
|
|
|
|
* The geometry of the OpenGL window currently being rendered to
|
|
|
|
* in the virtual geometry space the rendering system uses.
|
|
|
|
* @see setVirtualScreenGeometry
|
|
|
|
* @since 5.9
|
|
|
|
**/
|
|
|
|
static QRect virtualScreenGeometry() {
|
|
|
|
return s_virtualScreenGeometry;
|
|
|
|
}
|
|
|
|
|
2017-03-06 00:38:37 +00:00
|
|
|
/**
|
|
|
|
* The scale of the OpenGL window currently being rendered to
|
|
|
|
*
|
|
|
|
* @returns the ratio between the virtual geometry space the rendering
|
|
|
|
* system uses and the target
|
|
|
|
* @since 5.10
|
|
|
|
*/
|
|
|
|
static void setVirtualScreenScale(qreal scale) {
|
|
|
|
s_virtualScreenScale = scale;
|
|
|
|
}
|
|
|
|
|
|
|
|
static qreal virtualScreenScale() {
|
|
|
|
return s_virtualScreenScale;
|
|
|
|
}
|
|
|
|
|
2011-01-30 14:34:42 +00:00
|
|
|
|
|
|
|
protected:
|
|
|
|
void initFBO();
|
|
|
|
|
|
|
|
|
|
|
|
private:
|
2014-04-10 16:04:54 +00:00
|
|
|
friend void KWin::cleanupGL();
|
|
|
|
static void cleanup();
|
2011-02-04 16:30:36 +00:00
|
|
|
static bool sSupported;
|
2011-08-17 17:32:36 +00:00
|
|
|
static bool s_blitSupported;
|
2011-03-13 13:34:30 +00:00
|
|
|
static QStack<GLRenderTarget*> s_renderTargets;
|
2014-11-25 07:40:23 +00:00
|
|
|
static QSize s_virtualScreenSize;
|
2016-10-14 13:29:50 +00:00
|
|
|
static QRect s_virtualScreenGeometry;
|
2017-03-06 00:38:37 +00:00
|
|
|
static qreal s_virtualScreenScale;
|
2017-03-06 00:39:41 +00:00
|
|
|
static GLint s_virtualScreenViewport[4];
|
2011-01-30 14:34:42 +00:00
|
|
|
|
2011-07-17 15:57:30 +00:00
|
|
|
GLTexture mTexture;
|
2011-01-30 14:34:42 +00:00
|
|
|
bool mValid;
|
|
|
|
|
|
|
|
GLuint mFramebuffer;
|
2007-04-29 17:35:43 +00:00
|
|
|
};
|
|
|
|
|
2012-09-27 15:26:19 +00:00
|
|
|
enum VertexAttributeType {
|
|
|
|
VA_Position = 0,
|
|
|
|
VA_TexCoord = 1,
|
|
|
|
VertexAttributeCount = 2
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Describes the format of a vertex attribute stored in a buffer object.
|
|
|
|
*
|
|
|
|
* The attribute format consists of the attribute index, the number of
|
|
|
|
* vector components, the data type, and the offset of the first element
|
|
|
|
* relative to the start of the vertex data.
|
|
|
|
*/
|
|
|
|
struct GLVertexAttrib
|
|
|
|
{
|
|
|
|
int index; /** The attribute index */
|
|
|
|
int size; /** The number of components [1..4] */
|
|
|
|
GLenum type; /** The type (e.g. GL_FLOAT) */
|
|
|
|
int relativeOffset; /** The relative offset of the attribute */
|
|
|
|
};
|
|
|
|
|
2010-07-19 20:53:32 +00:00
|
|
|
/**
|
|
|
|
* @short Vertex Buffer Object
|
|
|
|
*
|
|
|
|
* This is a short helper class to use vertex buffer objects (VBO). A VBO can be used to buffer
|
|
|
|
* vertex data and to store them on graphics memory. It is the only allowed way to pass vertex
|
|
|
|
* data to the GPU in OpenGL ES 2 and OpenGL 3 with forward compatible mode.
|
|
|
|
*
|
2010-07-24 07:32:42 +00:00
|
|
|
* If VBOs are not supported on the used OpenGL profile this class falls back to legacy
|
|
|
|
* rendering using client arrays. Therefore this class should always be used for rendering geometries.
|
|
|
|
*
|
2013-03-12 12:17:53 +00:00
|
|
|
* @author Martin Gräßlin <mgraesslin@kde.org>
|
2010-07-19 20:53:32 +00:00
|
|
|
* @since 4.6
|
|
|
|
*/
|
2013-12-03 09:43:57 +00:00
|
|
|
class KWINGLUTILS_EXPORT GLVertexBuffer
|
2010-07-19 20:53:32 +00:00
|
|
|
{
|
2011-01-30 14:34:42 +00:00
|
|
|
public:
|
|
|
|
/**
|
|
|
|
* Enum to define how often the vertex data in the buffer object changes.
|
|
|
|
*/
|
|
|
|
enum UsageHint {
|
|
|
|
Dynamic, ///< frequent changes, but used several times for rendering
|
|
|
|
Static, ///< No changes to data
|
|
|
|
Stream ///< Data only used once for rendering, updated very frequently
|
|
|
|
};
|
2010-12-11 14:52:21 +00:00
|
|
|
|
2012-12-29 06:34:38 +00:00
|
|
|
explicit GLVertexBuffer(UsageHint hint);
|
2011-01-30 14:34:42 +00:00
|
|
|
~GLVertexBuffer();
|
|
|
|
|
2012-09-27 15:26:19 +00:00
|
|
|
/**
|
|
|
|
* Specifies how interleaved vertex attributes are laid out in
|
|
|
|
* the buffer object.
|
|
|
|
*
|
|
|
|
* Note that the attributes and the stride should be 32 bit aligned
|
|
|
|
* or a performance penalty may be incurred.
|
|
|
|
*
|
|
|
|
* For some hardware the optimal stride is a multiple of 32 bytes.
|
|
|
|
*
|
|
|
|
* Example:
|
|
|
|
*
|
|
|
|
* struct Vertex {
|
|
|
|
* QVector3D position;
|
|
|
|
* QVector2D texcoord;
|
|
|
|
* };
|
|
|
|
*
|
|
|
|
* const GLVertexAttrib attribs[] = {
|
|
|
|
* { VA_Position, 3, GL_FLOAT, offsetof(Vertex, position) },
|
|
|
|
* { VA_TexCoord, 2, GL_FLOAT, offsetof(Vertex, texcoord) }
|
|
|
|
* };
|
|
|
|
*
|
|
|
|
* Vertex vertices[6];
|
|
|
|
* vbo->setAttribLayout(attribs, 2, sizeof(Vertex));
|
|
|
|
* vbo->setData(vertices, sizeof(vertices));
|
|
|
|
*/
|
|
|
|
void setAttribLayout(const GLVertexAttrib *attribs, int count, int stride);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Uploads data into the buffer object's data store.
|
|
|
|
*/
|
|
|
|
void setData(const void *data, size_t sizeInBytes);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets the number of vertices that will be drawn by the render() method.
|
|
|
|
*/
|
|
|
|
void setVertexCount(int count);
|
|
|
|
|
2011-01-30 14:34:42 +00:00
|
|
|
/**
|
|
|
|
* Sets the vertex data.
|
|
|
|
* @param numberVertices The number of vertices in the arrays
|
|
|
|
* @param dim The dimension of the vertices: 2 for x/y, 3 for x/y/z
|
|
|
|
* @param vertices The vertices, size must equal @a numberVertices * @a dim
|
|
|
|
* @param texcoords The texture coordinates for each vertex.
|
|
|
|
* Size must equal 2 * @a numberVertices.
|
|
|
|
*/
|
|
|
|
void setData(int numberVertices, int dim, const float* vertices, const float* texcoords);
|
2012-09-26 15:17:09 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Maps an unused range of the data store into the client's address space.
|
|
|
|
*
|
|
|
|
* The data store will be reallocated if it is smaller than the given size.
|
|
|
|
*
|
|
|
|
* The buffer object is mapped for writing, not reading. Attempts to read from
|
|
|
|
* the mapped buffer range may result in system errors, including program
|
|
|
|
* termination. The data in the mapped region is undefined until it has been
|
|
|
|
* written to. If subsequent GL calls access unwritten memory, the results are
|
|
|
|
* undefined and system errors, including program termination, may occur.
|
|
|
|
*
|
|
|
|
* No GL calls that access the buffer object must be made while the buffer
|
|
|
|
* object is mapped. The returned pointer must not be passed as a parameter
|
|
|
|
* value to any GL function.
|
|
|
|
*
|
|
|
|
* It is assumed that the GL_ARRAY_BUFFER_BINDING will not be changed while
|
|
|
|
* the buffer object is mapped.
|
|
|
|
*/
|
|
|
|
GLvoid *map(size_t size);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Flushes the mapped buffer range and unmaps the buffer.
|
|
|
|
*/
|
|
|
|
void unmap();
|
|
|
|
|
2013-03-18 15:43:08 +00:00
|
|
|
/**
|
|
|
|
* Binds the vertex arrays to the context.
|
|
|
|
*/
|
|
|
|
void bindArrays();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Disables the vertex arrays.
|
|
|
|
*/
|
|
|
|
void unbindArrays();
|
|
|
|
|
2013-06-10 20:21:16 +00:00
|
|
|
/**
|
|
|
|
* Draws count vertices beginning with first.
|
|
|
|
*/
|
|
|
|
void draw(GLenum primitiveMode, int first, int count);
|
|
|
|
|
2013-03-18 15:43:08 +00:00
|
|
|
/**
|
|
|
|
* Draws count vertices beginning with first.
|
|
|
|
*/
|
|
|
|
void draw(const QRegion ®ion, GLenum primitiveMode, int first, int count, bool hardwareClipping = false);
|
|
|
|
|
2011-01-30 14:34:42 +00:00
|
|
|
/**
|
|
|
|
* Renders the vertex data in given @a primitiveMode.
|
|
|
|
* Please refer to OpenGL documentation of glDrawArrays or glDrawElements for allowed
|
|
|
|
* values for @a primitiveMode. Best is to use GL_TRIANGLES or similar to be future
|
|
|
|
* compatible.
|
|
|
|
*/
|
|
|
|
void render(GLenum primitiveMode);
|
|
|
|
/**
|
2012-02-12 15:42:09 +00:00
|
|
|
* Same as above restricting painting to @a region if @a hardwareClipping is true.
|
|
|
|
* It's within the caller's responsibility to enable GL_SCISSOR_TEST.
|
2011-01-30 14:34:42 +00:00
|
|
|
*/
|
2012-02-12 15:42:09 +00:00
|
|
|
void render(const QRegion& region, GLenum primitiveMode, bool hardwareClipping = false);
|
2011-01-30 14:34:42 +00:00
|
|
|
/**
|
|
|
|
* Sets the color the geometry will be rendered with.
|
|
|
|
* For legacy rendering glColor is used before rendering the geometry.
|
|
|
|
* For core shader a uniform "geometryColor" is expected and is set.
|
|
|
|
* @param color The color to render the geometry
|
|
|
|
* @param enableColor Whether the geometry should be rendered with a color or not
|
|
|
|
* @see setUseColor
|
|
|
|
* @see isUseColor
|
|
|
|
* @since 4.7
|
|
|
|
**/
|
|
|
|
void setColor(const QColor& color, bool enableColor = true);
|
|
|
|
/**
|
|
|
|
* @return @c true if geometry will be painted with a color, @c false otherwise
|
|
|
|
* @see setUseColor
|
|
|
|
* @see setColor
|
|
|
|
* @since 4.7
|
|
|
|
**/
|
|
|
|
bool isUseColor() const;
|
|
|
|
/**
|
|
|
|
* Enables/Disables rendering the geometry with a color.
|
|
|
|
* If no color is set an opaque, black color is used.
|
|
|
|
* @param enable Enable/Disable rendering with color
|
|
|
|
* @see isUseColor
|
|
|
|
* @see setColor
|
|
|
|
* @since 4.7
|
|
|
|
**/
|
|
|
|
void setUseColor(bool enable);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Resets the instance to default values.
|
|
|
|
* Useful for shared buffers.
|
|
|
|
* @since 4.7
|
|
|
|
**/
|
|
|
|
void reset();
|
|
|
|
|
2014-12-03 18:41:38 +00:00
|
|
|
/**
|
|
|
|
* Notifies the vertex buffer that we are done painting the frame.
|
|
|
|
*
|
|
|
|
* @internal
|
|
|
|
*/
|
|
|
|
void endOfFrame();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Notifies the vertex buffer that we have posted the frame.
|
|
|
|
*
|
|
|
|
* @internal
|
|
|
|
*/
|
|
|
|
void framePosted();
|
|
|
|
|
2011-01-30 14:34:42 +00:00
|
|
|
/**
|
|
|
|
* @internal
|
|
|
|
*/
|
|
|
|
static void initStatic();
|
2013-03-21 22:02:07 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @internal
|
|
|
|
*/
|
|
|
|
static void cleanup();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns true if indexed quad mode is supported, and false otherwise.
|
|
|
|
*/
|
|
|
|
static bool supportsIndexedQuads();
|
|
|
|
|
2011-01-30 14:34:42 +00:00
|
|
|
/**
|
|
|
|
* @return A shared VBO for streaming data
|
|
|
|
* @since 4.7
|
|
|
|
**/
|
|
|
|
static GLVertexBuffer *streamingBuffer();
|
|
|
|
|
2016-10-06 07:57:56 +00:00
|
|
|
/**
|
|
|
|
* Sets the virtual screen geometry to @p g.
|
|
|
|
* This is the geometry of the OpenGL window currently being rendered to
|
|
|
|
* in the virtual geometry space the rendering geometries use.
|
|
|
|
* @since 5.9
|
|
|
|
**/
|
|
|
|
static void setVirtualScreenGeometry(const QRect &g) {
|
|
|
|
s_virtualScreenGeometry = g;
|
|
|
|
}
|
|
|
|
|
2017-10-26 16:15:31 +00:00
|
|
|
/**
|
|
|
|
* The scale of the OpenGL window currently being rendered to
|
|
|
|
*
|
|
|
|
* @returns the ratio between the virtual geometry space the rendering
|
|
|
|
* system uses and the target
|
|
|
|
* @since 5.11.3
|
|
|
|
*/
|
|
|
|
static void setVirtualScreenScale(qreal s) {
|
|
|
|
s_virtualScreenScale = s;
|
|
|
|
}
|
|
|
|
|
2011-01-30 14:34:42 +00:00
|
|
|
private:
|
|
|
|
GLVertexBufferPrivate* const d;
|
2016-10-06 07:57:56 +00:00
|
|
|
static QRect s_virtualScreenGeometry;
|
2017-10-26 16:15:31 +00:00
|
|
|
static qreal s_virtualScreenScale;
|
2010-07-19 20:53:32 +00:00
|
|
|
};
|
|
|
|
|
2007-04-29 17:35:43 +00:00
|
|
|
} // namespace
|
|
|
|
|
2014-04-01 16:07:23 +00:00
|
|
|
Q_DECLARE_OPERATORS_FOR_FLAGS(KWin::ShaderTraits)
|
|
|
|
|
2008-01-16 18:13:24 +00:00
|
|
|
/** @} */
|
|
|
|
|
2007-05-07 11:46:01 +00:00
|
|
|
#endif
|