Adding color to VBO.
A color can be specified to render the geometry of the VBO. For legacy painting glColor is used, for shader a uniform is set. In order to allow rendering without texcoords, it is possible to pass a null pointer as texcoords. Shader added to scene which just renders a colored geometry without texturing.
This commit is contained in:
parent
979490c134
commit
ae95ab0c43
9 changed files with 125 additions and 10 deletions
|
@ -1229,6 +1229,8 @@ class GLVertexBufferPrivate
|
|||
, numberVertices( 0 )
|
||||
, dimension( 2 )
|
||||
, useShader( false )
|
||||
, useColor( false )
|
||||
, color( 0, 0, 0, 255 )
|
||||
{
|
||||
if( GLVertexBufferPrivate::supported )
|
||||
{
|
||||
|
@ -1250,6 +1252,8 @@ class GLVertexBufferPrivate
|
|||
static bool supported;
|
||||
QVector<float> legacyVertices;
|
||||
QVector<float> legacyTexCoords;
|
||||
bool useColor;
|
||||
QColor color;
|
||||
|
||||
void legacyPainting( QRegion region, GLenum primitiveMode );
|
||||
void corePainting( const QRegion& region, GLenum primitiveMode );
|
||||
|
@ -1262,8 +1266,14 @@ void GLVertexBufferPrivate::legacyPainting( QRegion region, GLenum primitiveMode
|
|||
// Enable arrays
|
||||
glEnableClientState( GL_VERTEX_ARRAY );
|
||||
glVertexPointer( dimension, GL_FLOAT, 0, legacyVertices.constData() );
|
||||
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
glTexCoordPointer( 2, GL_FLOAT, 0, legacyTexCoords.constData() );
|
||||
if (!legacyTexCoords.isEmpty()) {
|
||||
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
glTexCoordPointer( 2, GL_FLOAT, 0, legacyTexCoords.constData() );
|
||||
}
|
||||
|
||||
if (useColor) {
|
||||
glColor4f(color.redF(), color.greenF(), color.blueF(), color.alphaF());
|
||||
}
|
||||
|
||||
// Clip using scissoring
|
||||
PaintClipper pc( region );
|
||||
|
@ -1275,7 +1285,9 @@ void GLVertexBufferPrivate::legacyPainting( QRegion region, GLenum primitiveMode
|
|||
}
|
||||
|
||||
glDisableClientState( GL_VERTEX_ARRAY );
|
||||
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
if (!legacyTexCoords.isEmpty()) {
|
||||
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1296,6 +1308,13 @@ void GLVertexBufferPrivate::corePainting( const QRegion& region, GLenum primitiv
|
|||
glBindBuffer( GL_ARRAY_BUFFER, buffers[ 1 ] );
|
||||
glVertexAttribPointer( texAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0 );
|
||||
|
||||
if (useColor) {
|
||||
GLint colorLocation = glGetUniformLocation(currentProgram, "geometryColor");
|
||||
if (colorLocation != 0) {
|
||||
glUniform4f(currentProgram, color.redF(), color.greenF(), color.blueF(), color.alphaF());
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: reenable paint clipper
|
||||
// Clip using scissoring
|
||||
PaintClipper pc( region );
|
||||
|
@ -1339,11 +1358,12 @@ void GLVertexBuffer::setData( int numberVertices, int dim, const float* vertices
|
|||
d->legacyVertices << vertices[i];
|
||||
}
|
||||
d->legacyTexCoords.clear();
|
||||
d->legacyTexCoords.reserve( numberVertices * 2 );
|
||||
for( int i=0; i<numberVertices*2; ++i)
|
||||
{
|
||||
d->legacyTexCoords << texcoords[i];
|
||||
if (texcoords != NULL) {
|
||||
d->legacyTexCoords.reserve( numberVertices * 2 );
|
||||
for (int i=0; i<numberVertices*2; ++i) {
|
||||
d->legacyTexCoords << texcoords[i];
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
GLenum hint;
|
||||
|
@ -1366,8 +1386,10 @@ void GLVertexBuffer::setData( int numberVertices, int dim, const float* vertices
|
|||
glBindBuffer( GL_ARRAY_BUFFER, d->buffers[ 0 ] );
|
||||
glBufferData( GL_ARRAY_BUFFER, sizeof(GLfloat)*numberVertices*d->dimension, vertices, hint );
|
||||
|
||||
glBindBuffer( GL_ARRAY_BUFFER, d->buffers[ 1 ] );
|
||||
glBufferData( GL_ARRAY_BUFFER, sizeof(GLfloat)*numberVertices*2, texcoords, hint );
|
||||
if (texcoords != NULL) {
|
||||
glBindBuffer( GL_ARRAY_BUFFER, d->buffers[ 1 ] );
|
||||
glBufferData( GL_ARRAY_BUFFER, sizeof(GLfloat)*numberVertices*2, texcoords, hint );
|
||||
}
|
||||
|
||||
glBindBuffer( GL_ARRAY_BUFFER, 0 );
|
||||
}
|
||||
|
@ -1398,6 +1420,10 @@ void GLVertexBuffer::render( const QRegion& region, GLenum primitiveMode )
|
|||
glBindBuffer( GL_ARRAY_BUFFER, d->buffers[ 1 ] );
|
||||
glTexCoordPointer( 2, GL_FLOAT, 0, 0 );
|
||||
|
||||
if (d->useColor) {
|
||||
glColor4f(d->color.redF(), d->color.greenF(), d->color.blueF(), d->color.alphaF());
|
||||
}
|
||||
|
||||
// Clip using scissoring
|
||||
PaintClipper pc( region );
|
||||
for( PaintClipper::Iterator iterator;
|
||||
|
@ -1429,6 +1455,22 @@ bool GLVertexBuffer::isSupported()
|
|||
return GLVertexBufferPrivate::supported;
|
||||
}
|
||||
|
||||
bool GLVertexBuffer::isUseColor() const
|
||||
{
|
||||
return d->useColor;
|
||||
}
|
||||
|
||||
void GLVertexBuffer::setUseColor(bool enable)
|
||||
{
|
||||
d->useColor = enable;
|
||||
}
|
||||
|
||||
void GLVertexBuffer::setColor(const QColor& color, bool enable)
|
||||
{
|
||||
d->useColor = enable;
|
||||
d->color = color;
|
||||
}
|
||||
|
||||
void GLVertexBuffer::initStatic()
|
||||
{
|
||||
#ifdef KWIN_HAVE_OPENGLES
|
||||
|
|
|
@ -404,6 +404,33 @@ class KWIN_EXPORT GLVertexBuffer
|
|||
* @since 4.7
|
||||
**/
|
||||
bool isUseShader() const;
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* @internal
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
<file>lanczos-fragment.glsl</file>
|
||||
<file>scene-vertex.glsl</file>
|
||||
<file>scene-fragment.glsl</file>
|
||||
<file>scene-color-vertex.glsl</file>
|
||||
<file>scene-color-fragment.glsl</file>
|
||||
<file>scene-generic-vertex.glsl</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
11
scene-color-fragment.glsl
Normal file
11
scene-color-fragment.glsl
Normal file
|
@ -0,0 +1,11 @@
|
|||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
#endif
|
||||
uniform vec4 geometryColor;
|
||||
|
||||
// not used
|
||||
varying vec2 varyingTexCoords;
|
||||
|
||||
void main() {
|
||||
gl_FragColor = geometryColor;
|
||||
}
|
14
scene-color-vertex.glsl
Normal file
14
scene-color-vertex.glsl
Normal file
|
@ -0,0 +1,14 @@
|
|||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
#endif
|
||||
// size of the complete display in pixels, x==width, y==height
|
||||
uniform vec2 displaySize;
|
||||
// geometry of the window/texture to be rendered: x, y, width, height in display geometry
|
||||
uniform vec4 geometry;
|
||||
|
||||
// passed in vertex - only x and y are used
|
||||
attribute vec4 vertex;
|
||||
|
||||
void main() {
|
||||
gl_Position.xy = 2.0*vec2(geometry.x + vertex.x, displaySize.y - vertex.y - geometry.y)/displaySize - vertex.ww;
|
||||
}
|
|
@ -166,6 +166,22 @@ bool SceneOpenGL::setupSceneShaders()
|
|||
kDebug(1212) << "Generic Scene Shader is not valid";
|
||||
return false;
|
||||
}
|
||||
m_colorShader = new GLShader(":/resources/scene-color-vertex.glsl", ":/resources/scene-color-fragment.glsl");
|
||||
if (m_colorShader->isValid()) {
|
||||
m_colorShader->bind();
|
||||
m_colorShader->setUniform("displaySize", QVector2D(displayWidth(), displayHeight()));
|
||||
m_colorShader->unbind();
|
||||
kDebug(1212) << "Color Shader is valid";
|
||||
} else {
|
||||
delete m_genericSceneShader;
|
||||
m_genericSceneShader = NULL;
|
||||
delete m_sceneShader;
|
||||
m_sceneShader = NULL;
|
||||
delete m_colorShader;
|
||||
m_colorShader = NULL;
|
||||
kDebug(1212) << "Color Scene Shader is not valid";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ class SceneOpenGL
|
|||
virtual void windowDeleted( Deleted* );
|
||||
GLShader* sceneShader() const;
|
||||
bool hasSceneShader() const {
|
||||
return m_sceneShader != NULL && m_genericSceneShader != NULL;
|
||||
return m_sceneShader != NULL && m_genericSceneShader != NULL && m_colorShader != NULL;
|
||||
}
|
||||
protected:
|
||||
virtual void paintGenericScreen( int mask, ScreenPaintData data );
|
||||
|
@ -109,6 +109,7 @@ class SceneOpenGL
|
|||
bool selfCheckDone;
|
||||
GLShader* m_sceneShader;
|
||||
GLShader* m_genericSceneShader;
|
||||
GLShader* m_colorShader;
|
||||
bool debug;
|
||||
};
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ SceneOpenGL::SceneOpenGL( Workspace* ws )
|
|||
, selfCheckDone( true )
|
||||
, m_sceneShader( NULL )
|
||||
, m_genericSceneShader( NULL )
|
||||
, m_colorShader( NULL )
|
||||
{
|
||||
if( !initRenderingContext() )
|
||||
return;
|
||||
|
|
|
@ -41,6 +41,7 @@ SceneOpenGL::SceneOpenGL( Workspace* ws )
|
|||
, selfCheckDone( false )
|
||||
, m_sceneShader( NULL )
|
||||
, m_genericSceneShader( NULL )
|
||||
, m_colorShader( NULL )
|
||||
{
|
||||
if( !Extensions::glxAvailable())
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue