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:
Martin Gräßlin 2010-12-05 09:13:46 +01:00 committed by Martin Gräßlin
parent 979490c134
commit ae95ab0c43
9 changed files with 125 additions and 10 deletions

View file

@ -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

View file

@ -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

View file

@ -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
View 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
View 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;
}

View file

@ -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;
}

View file

@ -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;
};

View file

@ -33,6 +33,7 @@ SceneOpenGL::SceneOpenGL( Workspace* ws )
, selfCheckDone( true )
, m_sceneShader( NULL )
, m_genericSceneShader( NULL )
, m_colorShader( NULL )
{
if( !initRenderingContext() )
return;

View file

@ -41,6 +41,7 @@ SceneOpenGL::SceneOpenGL( Workspace* ws )
, selfCheckDone( false )
, m_sceneShader( NULL )
, m_genericSceneShader( NULL )
, m_colorShader( NULL )
{
if( !Extensions::glxAvailable())
{