Adding a generic scene shader able to handle transformation
Currently only window transformations are supported.
This commit is contained in:
parent
a2e214d326
commit
eb7d06d22f
6 changed files with 122 additions and 43 deletions
|
@ -4,5 +4,6 @@
|
|||
<file>lanczos-fragment.glsl</file>
|
||||
<file>scene-vertex.glsl</file>
|
||||
<file>scene-fragment.glsl</file>
|
||||
<file>scene-generic-vertex.glsl</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
19
scene-generic-vertex.glsl
Normal file
19
scene-generic-vertex.glsl
Normal file
|
@ -0,0 +1,19 @@
|
|||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
#endif
|
||||
uniform mat4 projection;
|
||||
uniform mat4 modelview;
|
||||
uniform mat4 windowTransformation;
|
||||
|
||||
// passed in vertex - only x and y are used
|
||||
attribute vec4 vertex;
|
||||
// passed in texCoords - to be forwarded
|
||||
attribute vec2 texCoord;
|
||||
|
||||
// texCoords passed to fragment shader
|
||||
varying vec2 varyingTexCoords;
|
||||
|
||||
void main() {
|
||||
varyingTexCoords = texCoord;
|
||||
gl_Position = vertex*(windowTransformation*modelview)*projection;
|
||||
}
|
101
scene_opengl.cpp
101
scene_opengl.cpp
|
@ -92,6 +92,7 @@ Sources and other compositing managers:
|
|||
#include <qpainter.h>
|
||||
#include <QVector2D>
|
||||
#include <QVector4D>
|
||||
#include <QMatrix4x4>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
@ -115,6 +116,59 @@ XShmSegmentInfo SceneOpenGL::shm;
|
|||
#include "scene_opengl_glx.cpp"
|
||||
#endif
|
||||
|
||||
|
||||
bool SceneOpenGL::setupSceneShaders()
|
||||
{
|
||||
m_sceneShader = new GLShader(":/resources/scene-vertex.glsl", ":/resources/scene-fragment.glsl");
|
||||
if (m_sceneShader->isValid()) {
|
||||
m_sceneShader->bind();
|
||||
m_sceneShader->setUniform("sample", 0);
|
||||
m_sceneShader->setUniform("displaySize", QVector2D(displayWidth(), displayHeight()));
|
||||
m_sceneShader->setUniform("debug", debug ? 1 : 0);
|
||||
m_sceneShader->unbind();
|
||||
kDebug(1212) << "Scene Shader is valid";
|
||||
}
|
||||
else {
|
||||
delete m_sceneShader;
|
||||
m_sceneShader = NULL;
|
||||
kDebug(1212) << "Scene Shader is not valid";
|
||||
return false;
|
||||
}
|
||||
m_genericSceneShader = new GLShader( ":/resources/scene-generic-vertex.glsl", ":/resources/scene-fragment.glsl" );
|
||||
if (m_genericSceneShader->isValid()) {
|
||||
m_genericSceneShader->bind();
|
||||
m_genericSceneShader->setUniform("sample", 0);
|
||||
m_genericSceneShader->setUniform("debug", debug ? 1 : 0);
|
||||
QMatrix4x4 projection;
|
||||
float fovy = 60.0f;
|
||||
float aspect = 1.0f;
|
||||
float zNear = 0.1f;
|
||||
float zFar = 100.0f;
|
||||
float ymax = zNear * tan(fovy * M_PI / 360.0f);
|
||||
float ymin = -ymax;
|
||||
float xmin = ymin * aspect;
|
||||
float xmax = ymax * aspect;
|
||||
projection.frustum(xmin, xmax, ymin, ymax, zNear, zFar);
|
||||
m_genericSceneShader->setUniform("projection", projection);
|
||||
QMatrix4x4 modelview;
|
||||
float scaleFactor = 1.1 * tan( fovy * M_PI / 360.0f )/ymax;
|
||||
modelview.translate(xmin*scaleFactor, ymax*scaleFactor, -1.1);
|
||||
modelview.scale((xmax-xmin)*scaleFactor/displayWidth(), -(ymax-ymin)*scaleFactor/displayHeight(), 0.001);
|
||||
m_genericSceneShader->setUniform("modelview", modelview);
|
||||
m_genericSceneShader->unbind();
|
||||
kDebug(1212) << "Generic Scene Shader is valid";
|
||||
}
|
||||
else {
|
||||
delete m_genericSceneShader;
|
||||
m_genericSceneShader = NULL;
|
||||
delete m_sceneShader;
|
||||
m_sceneShader = NULL;
|
||||
kDebug(1212) << "Generic Scene Shader is not valid";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SceneOpenGL::initFailed() const
|
||||
{
|
||||
return !init_ok;
|
||||
|
@ -458,20 +512,51 @@ void SceneOpenGL::Window::performPaint( int mask, QRegion region, WindowPaintDat
|
|||
int y = toplevel->y();
|
||||
double z = 0.0;
|
||||
bool sceneShader = false;
|
||||
if( !data.shader && !( mask & PAINT_WINDOW_TRANSFORMED ) && !( mask & PAINT_SCREEN_TRANSFORMED ) )
|
||||
{
|
||||
if (!data.shader) {
|
||||
// set the shader for uniform initialising in paint decoration
|
||||
data.shader = static_cast<SceneOpenGL*>(scene)->m_sceneShader;
|
||||
sceneShader = true;
|
||||
data.shader->bind();
|
||||
data.shader->setUniform("geometry", QVector4D(x, y, toplevel->width(), toplevel->height()));
|
||||
if ((mask & PAINT_WINDOW_TRANSFORMED) || (mask & PAINT_SCREEN_TRANSFORMED)) {
|
||||
data.shader = static_cast<SceneOpenGL*>(scene)->m_genericSceneShader;
|
||||
data.shader->bind();
|
||||
} else {
|
||||
data.shader = static_cast<SceneOpenGL*>(scene)->m_sceneShader;
|
||||
data.shader->bind();
|
||||
data.shader->setUniform("geometry", QVector4D(x, y, toplevel->width(), toplevel->height()));
|
||||
}
|
||||
if( mask & PAINT_WINDOW_TRANSFORMED )
|
||||
{
|
||||
sceneShader = true;
|
||||
}
|
||||
if (mask & PAINT_WINDOW_TRANSFORMED) {
|
||||
x += data.xTranslate;
|
||||
y += data.yTranslate;
|
||||
z += data.zTranslate;
|
||||
QMatrix4x4 windowTransformation;
|
||||
windowTransformation.translate(x, y, z);
|
||||
if ((mask & PAINT_WINDOW_TRANSFORMED ) && ( data.xScale != 1 || data.yScale != 1 || data.zScale != 1)) {
|
||||
windowTransformation.scale(data.xScale, data.yScale, data.zScale);
|
||||
}
|
||||
if ((mask & PAINT_WINDOW_TRANSFORMED) && data.rotation) {
|
||||
windowTransformation.translate(data.rotation->xRotationPoint, data.rotation->yRotationPoint, data.rotation->zRotationPoint);
|
||||
qreal xAxis = 0.0;
|
||||
qreal yAxis = 0.0;
|
||||
qreal zAxis = 0.0;
|
||||
switch( data.rotation->axis )
|
||||
{
|
||||
case RotationData::XAxis:
|
||||
xAxis = 1.0;
|
||||
break;
|
||||
case RotationData::YAxis:
|
||||
yAxis = 1.0;
|
||||
break;
|
||||
case RotationData::ZAxis:
|
||||
zAxis = 1.0;
|
||||
break;
|
||||
}
|
||||
windowTransformation.rotate(data.rotation->angle, xAxis, yAxis, zAxis);
|
||||
windowTransformation.translate(-data.rotation->xRotationPoint, -data.rotation->yRotationPoint, -data.rotation->zRotationPoint);
|
||||
}
|
||||
if (sceneShader) {
|
||||
data.shader->setUniform("windowTransformation", windowTransformation);
|
||||
}
|
||||
}
|
||||
if( !sceneShader )
|
||||
{
|
||||
#ifndef KWIN_HAVE_OPENGLES
|
||||
|
|
|
@ -69,6 +69,7 @@ class SceneOpenGL
|
|||
bool selfCheck();
|
||||
void selfCheckSetup();
|
||||
bool selfCheckFinish();
|
||||
bool setupSceneShaders();
|
||||
GC gcroot;
|
||||
class FBConfigInfo
|
||||
{
|
||||
|
@ -104,6 +105,7 @@ class SceneOpenGL
|
|||
bool init_ok;
|
||||
bool selfCheckDone;
|
||||
GLShader* m_sceneShader;
|
||||
GLShader* m_genericSceneShader;
|
||||
bool debug;
|
||||
};
|
||||
|
||||
|
|
|
@ -32,30 +32,18 @@ SceneOpenGL::SceneOpenGL( Workspace* ws )
|
|||
, init_ok( false )
|
||||
, selfCheckDone( true )
|
||||
, m_sceneShader( NULL )
|
||||
, m_genericSceneShader( NULL )
|
||||
{
|
||||
if( !initRenderingContext() )
|
||||
return;
|
||||
|
||||
initGL();
|
||||
debug = qstrcmp( qgetenv( "KWIN_GL_DEBUG" ), "1" ) == 0;
|
||||
|
||||
m_sceneShader = new GLShader( ":/resources/scene-vertex.glsl", ":/resources/scene-fragment.glsl" );
|
||||
if( m_sceneShader->isValid() )
|
||||
{
|
||||
m_sceneShader->bind();
|
||||
m_sceneShader->setUniform( "sample", 0 );
|
||||
m_sceneShader->setUniform( "displaySize", QVector2D(displayWidth(), displayHeight()));
|
||||
m_sceneShader->setUniform( "debug", debug ? 1 : 0 );
|
||||
m_sceneShader->unbind();
|
||||
kDebug(1212) << "Scene Shader is valid";
|
||||
}
|
||||
else
|
||||
{
|
||||
delete m_sceneShader;
|
||||
m_sceneShader = NULL;
|
||||
kDebug(1212) << "Scene Shader is not valid";
|
||||
if (!setupSceneShaders()) {
|
||||
kError( 1212 ) << "Shaders not valid, ES compositing not possible";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( checkGLError( "Init" ))
|
||||
{
|
||||
|
|
|
@ -40,6 +40,7 @@ SceneOpenGL::SceneOpenGL( Workspace* ws )
|
|||
, init_ok( false )
|
||||
, selfCheckDone( false )
|
||||
, m_sceneShader( NULL )
|
||||
, m_genericSceneShader( NULL )
|
||||
{
|
||||
if( !Extensions::glxAvailable())
|
||||
{
|
||||
|
@ -99,24 +100,7 @@ SceneOpenGL::SceneOpenGL( Workspace* ws )
|
|||
GLPlatform::instance()->detect();
|
||||
if( GLPlatform::instance()->supports( GLSL ) )
|
||||
{
|
||||
m_sceneShader = new GLShader( ":/resources/scene-vertex.glsl", ":/resources/scene-fragment.glsl" );
|
||||
if( m_sceneShader->isValid() )
|
||||
{
|
||||
m_sceneShader->bind();
|
||||
m_sceneShader->setUniform( "sample", 0 );
|
||||
m_sceneShader->setUniform( "displaySize", QVector2D(displayWidth(), displayHeight()));
|
||||
m_sceneShader->setUniform( "debug", debug ? 1 : 0 );
|
||||
m_sceneShader->bindAttributeLocation( 0, "vertex" );
|
||||
m_sceneShader->bindAttributeLocation( 1, "texCoord" );
|
||||
m_sceneShader->unbind();
|
||||
kDebug(1212) << "Scene Shader is valid";
|
||||
}
|
||||
else
|
||||
{
|
||||
delete m_sceneShader;
|
||||
m_sceneShader = NULL;
|
||||
kDebug(1212) << "Scene Shader is not valid";
|
||||
}
|
||||
setupSceneShader();
|
||||
}
|
||||
|
||||
// OpenGL scene setup
|
||||
|
|
Loading…
Reference in a new issue