bool GLScreen::glPaintOutput (const GLScreenPaintAttrib &sAttrib, const GLMatrix &transform, const CompRegion ®ion, CompOutput *output, unsigned int mask) { WRAPABLE_HND_FUNCTN_RETURN (bool, glPaintOutput, sAttrib, transform, region, output, mask) GLMatrix sTransform = transform; if (mask & PAINT_SCREEN_REGION_MASK) { if (mask & PAINT_SCREEN_TRANSFORMED_MASK) { if (mask & PAINT_SCREEN_FULL_MASK) { glPaintTransformedOutput (sAttrib, sTransform, CompRegion (*output), output, mask); return true; } return false; } setLighting (false); sTransform.toScreenSpace (output, -DEFAULT_Z_CAMERA); /* * Sometimes region might be empty but we still need to force the * repaint. This can happen when a fullscreen window is unredirected, * and damageScreen is called. CompositeScreen::handlePaintTimeout * then subtracts the whole screen of damage because it's an overlay * and we're left with an empty damage region. * Even when this happens we may want to force the repaint if * windows are getting transformed (and so the unredirected window * needs to be redirected again). */ if (!region.isEmpty () || (mask & PAINT_SCREEN_FULL_MASK) || (mask & PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK)) priv->paintOutputRegion (sTransform, region, output, mask); return true; } else if (mask & PAINT_SCREEN_FULL_MASK) { glPaintTransformedOutput (sAttrib, sTransform, CompRegion (*output), output, mask); return true; } else { return false; } }
bool ShowrepaintScreen::glPaintOutput (const GLScreenPaintAttrib &attrib, const GLMatrix &transform, const CompRegion ®ion, CompOutput *output, unsigned int mask) { bool status; GLMatrix sTransform; // initially identity matrix unsigned short color[4]; status = gScreen->glPaintOutput (attrib, transform, region, output, mask); tmpRegion = region.intersected (*output); if (tmpRegion.isEmpty ()) return status; sTransform.toScreenSpace (output, -DEFAULT_Z_CAMERA); color[3] = optionGetIntensity () * 0xffff / 100; color[0] = (rand () & 7) * color[3] / 8; color[1] = (rand () & 7) * color[3] / 8; color[2] = (rand () & 7) * color[3] / 8; glColor4usv (color); glPushMatrix (); glLoadMatrixf (sTransform.getMatrix ()); glEnable (GL_BLEND); glBegin (GL_QUADS); foreach (const CompRect &box, tmpRegion.rects ()) { glVertex2i (box.x1 (), box.y1 ()); glVertex2i (box.x1 (), box.y2 ()); glVertex2i (box.x2 (), box.y2 ()); glVertex2i (box.x2 (), box.y1 ()); } glEnd (); glDisable (GL_BLEND); glPopMatrix(); glColor4usv (defaultColor); return status; }
bool WSNamesScreen::glPaintOutput (const GLScreenPaintAttrib &attrib, const GLMatrix &transform, const CompRegion ®ion, CompOutput *output, unsigned int mask) { bool status; status = gScreen->glPaintOutput (attrib, transform, region, output, mask); if (textData.getWidth () && textData.getHeight ()) { GLMatrix sTransform (transform); sTransform.toScreenSpace (output, -DEFAULT_Z_CAMERA); drawText (sTransform); } return status; }
void GLScreen::glPaintCompositedOutput (const CompRegion ®ion, GLFramebufferObject *fbo, unsigned int mask) { WRAPABLE_HND_FUNCTN (glPaintCompositedOutput, region, fbo, mask) GLMatrix sTransform; const GLTexture::Matrix & texmatrix = fbo->tex ()->matrix (); GLVertexBuffer *streamingBuffer = GLVertexBuffer::streamingBuffer (); streamingBuffer->begin (GL_TRIANGLES); if (mask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK) { GLfloat tx1 = COMP_TEX_COORD_X (texmatrix, 0.0f); GLfloat tx2 = COMP_TEX_COORD_X (texmatrix, screen->width ()); GLfloat ty1 = 1.0 - COMP_TEX_COORD_Y (texmatrix, 0.0f); GLfloat ty2 = 1.0 - COMP_TEX_COORD_Y (texmatrix, screen->height ()); const GLfloat vertexData[] = { 0.0f, 0.0f, 0.0f, 0.0f, (float)screen->height (), 0.0f, (float)screen->width (), 0.0f, 0.0f, 0.0f, (float)screen->height (), 0.0f, (float)screen->width (), (float)screen->height (), 0.0f, (float)screen->width (), 0.0f, 0.0f, }; const GLfloat textureData[] = { tx1, ty1, tx1, ty2, tx2, ty1, tx1, ty2, tx2, ty2, tx2, ty1, }; streamingBuffer->addVertices (6, &vertexData[0]); streamingBuffer->addTexCoords (0, 6, &textureData[0]); } else { BoxPtr pBox = const_cast <Region> (region.handle ())->rects; int nBox = const_cast <Region> (region.handle ())->numRects; while (nBox--) { GLfloat tx1 = COMP_TEX_COORD_X (texmatrix, pBox->x1); GLfloat tx2 = COMP_TEX_COORD_X (texmatrix, pBox->x2); GLfloat ty1 = 1.0 - COMP_TEX_COORD_Y (texmatrix, pBox->y1); GLfloat ty2 = 1.0 - COMP_TEX_COORD_Y (texmatrix, pBox->y2); const GLfloat vertexData[] = { (float)pBox->x1, (float)pBox->y1, 0.0f, (float)pBox->x1, (float)pBox->y2, 0.0f, (float)pBox->x2, (float)pBox->y1, 0.0f, (float)pBox->x1, (float)pBox->y2, 0.0f, (float)pBox->x2, (float)pBox->y2, 0.0f, (float)pBox->x2, (float)pBox->y1, 0.0f, }; const GLfloat textureData[] = { tx1, ty1, tx1, ty2, tx2, ty1, tx1, ty2, tx2, ty2, tx2, ty1, }; streamingBuffer->addVertices (6, &vertexData[0]); streamingBuffer->addTexCoords (0, 6, &textureData[0]); pBox++; } } streamingBuffer->end (); fbo->tex ()->enable (GLTexture::Fast); sTransform.toScreenSpace (&screen->fullscreenOutput (), -DEFAULT_Z_CAMERA); streamingBuffer->render (sTransform); fbo->tex ()->disable (); }
void GLScreen::glPaintTransformedOutput (const GLScreenPaintAttrib &sAttrib, const GLMatrix &transform, const CompRegion ®ion, CompOutput *output, unsigned int mask) { WRAPABLE_HND_FUNCTN (glPaintTransformedOutput, sAttrib, transform, region, output, mask) GLMatrix sTransform = transform; if (mask & PAINT_SCREEN_CLEAR_MASK) clearTargetOutput (GL_COLOR_BUFFER_BIT); setLighting (true); glApplyTransform (sAttrib, output, &sTransform); if ((mask & CLIP_PLANE_MASK) == CLIP_PLANE_MASK) { if (transformIsSimple (sTransform)) { glEnableOutputClipping (sTransform, region, output); sTransform.toScreenSpace (output, -sAttrib.zTranslate); priv->paintOutputRegion (sTransform, region, output, mask); glDisableOutputClipping (); } else if ( (GL::fboEnabled && GL::fboStencilSupported) || GL::stencilBuffer ) { sTransform.toScreenSpace (output, -sAttrib.zTranslate); glClearStencil (0); glClear (GL_STENCIL_BUFFER_BIT); glEnable (GL_STENCIL_TEST); glStencilFunc (GL_ALWAYS, 1, 1); glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); GLVertexBuffer vb; vb.setAutoProgram (priv->autoProgram); glBufferStencil (sTransform, vb, output); glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); glStencilMask (1); vb.render (sTransform); glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glStencilFunc (GL_EQUAL, 1, 1); glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP); priv->paintOutputRegion (sTransform, region, output, mask); glDisable (GL_STENCIL_TEST); } else { // This won't look quite right but should never happen. // Give a warning? sTransform.toScreenSpace (output, -sAttrib.zTranslate); priv->paintOutputRegion (sTransform, region, output, mask); } } else { sTransform.toScreenSpace (output, -sAttrib.zTranslate); priv->paintOutputRegion (sTransform, region, output, mask); } }
void ResizeScreen::glPaintRectangle (const GLScreenPaintAttrib &sAttrib, const GLMatrix &transform, CompOutput *output, unsigned short *borderColor, unsigned short *fillColor) { GLVertexBuffer *streamingBuffer = GLVertexBuffer::streamingBuffer (); BoxRec box; GLMatrix sTransform (transform); GLfloat vertexData [12]; GLfloat vertexData2[24]; GLint origSrc, origDst; GLushort fc[4], bc[4]; #ifdef USE_GLES GLint origSrcAlpha, origDstAlpha; glGetIntegerv (GL_BLEND_SRC_RGB, &origSrc); glGetIntegerv (GL_BLEND_DST_RGB, &origDst); glGetIntegerv (GL_BLEND_SRC_ALPHA, &origSrcAlpha); glGetIntegerv (GL_BLEND_DST_ALPHA, &origDstAlpha); #else glGetIntegerv (GL_BLEND_SRC, &origSrc); glGetIntegerv (GL_BLEND_DST, &origDst); #endif /* Premultiply the alpha values */ bc[3] = (float) borderColor[3] / (float) 65535.0f; bc[0] = ((float) borderColor[0] / 65535.0f) * bc[3]; bc[1] = ((float) borderColor[1] / 65535.0f) * bc[3]; bc[2] = ((float) borderColor[2] / 65535.0f) * bc[3]; logic.getPaintRectangle (&box); vertexData[0] = box.x1; vertexData[1] = box.y1; vertexData[2] = 0.0f; vertexData[3] = box.x1; vertexData[4] = box.y2; vertexData[5] = 0.0f; vertexData[6] = box.x2; vertexData[7] = box.y1; vertexData[8] = 0.0f; vertexData[9] = box.x2; vertexData[10] = box.y2; vertexData[11] = 0.0f; // FIXME: this is a quick work-around. // GL_LINE_LOOP and GL_LINE_STRIP primitive types in the SGX Pvr X11 driver // take special number of vertices (and reorder them). Thus, usage of // those line primitive is currently not supported by our GLVertexBuffer // implementation. This is a quick workaround to make it all work until // we come up with a better GLVertexBuffer::render(...) function. vertexData2[0] = box.x1; vertexData2[1] = box.y1; vertexData2[2] = 0.0f; vertexData2[3] = box.x1; vertexData2[4] = box.y2; vertexData2[5] = 0.0f; vertexData2[6] = box.x1; vertexData2[7] = box.y2; vertexData2[8] = 0.0f; vertexData2[9] = box.x2; vertexData2[10] = box.y2; vertexData2[11] = 0.0f; vertexData2[12] = box.x2; vertexData2[13] = box.y2; vertexData2[14] = 0.0f; vertexData2[15] = box.x2; vertexData2[16] = box.y1; vertexData2[17] = 0.0f; vertexData2[18] = box.x2; vertexData2[19] = box.y1; vertexData2[20] = 0.0f; vertexData2[21] = box.x1; vertexData2[22] = box.y1; vertexData2[23] = 0.0f; sTransform.toScreenSpace (output, -DEFAULT_Z_CAMERA); glEnable (GL_BLEND); glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA); /* fill rectangle */ if (fillColor) { fc[3] = fillColor[3]; fc[0] = fillColor[0] * (unsigned long)fc[3] / 65535; fc[1] = fillColor[1] * (unsigned long)fc[3] / 65535; fc[2] = fillColor[2] * (unsigned long)fc[3] / 65535; streamingBuffer->begin (GL_TRIANGLE_STRIP); streamingBuffer->addColors (1, fc); streamingBuffer->addVertices (4, &vertexData[0]); streamingBuffer->end (); streamingBuffer->render (sTransform); } /* draw outline */ static const int borderWidth = 2; glLineWidth (borderWidth); streamingBuffer->begin (GL_LINES); streamingBuffer->addColors (1, borderColor); streamingBuffer->addVertices (8, &vertexData2[0]); streamingBuffer->end (); streamingBuffer->render (sTransform); glDisable (GL_BLEND); #ifdef USE_GLES glBlendFuncSeparate (origSrc, origDst, origSrcAlpha, origDstAlpha); #else glBlendFunc (origSrc, origDst); #endif CompositeScreen *cScreen = CompositeScreen::get (screen); CompRect damage (box.x1 - borderWidth, box.y1 - borderWidth, box.x2 - box.x1 + 2 * borderWidth, box.y2 - box.y1 + 2 * borderWidth); cScreen->damageRegion (damage); }
bool FireScreen::glPaintOutput (const GLScreenPaintAttrib &attrib, const GLMatrix &transform, const CompRegion ®ion, CompOutput *output, unsigned int mask) { bool status = gScreen->glPaintOutput (attrib, transform, region, output, mask); if ((!init && ps.active) || brightness < 1.0) { GLMatrix sTransform = transform; sTransform.toScreenSpace (output, -DEFAULT_Z_CAMERA); if (brightness < 1.0) { /* cover the screen with a rectangle and darken it * (coded as two GL_TRIANGLES for GLES compatibility) */ GLfloat vertices[18]; GLushort colors[24]; vertices[0] = (GLfloat)output->region ()->extents.x1; vertices[1] = (GLfloat)output->region ()->extents.y1; vertices[2] = 0.0f; vertices[3] = (GLfloat)output->region ()->extents.x1; vertices[4] = (GLfloat)output->region ()->extents.y2; vertices[5] = 0.0f; vertices[6] = (GLfloat)output->region ()->extents.x2; vertices[7] = (GLfloat)output->region ()->extents.y2; vertices[8] = 0.0f; vertices[9] = (GLfloat)output->region ()->extents.x2; vertices[10] = (GLfloat)output->region ()->extents.y2; vertices[11] = 0.0f; vertices[12] = (GLfloat)output->region ()->extents.x2; vertices[13] = (GLfloat)output->region ()->extents.y1; vertices[14] = 0.0f; vertices[15] = (GLfloat)output->region ()->extents.x1; vertices[16] = (GLfloat)output->region ()->extents.y1; vertices[17] = 0.0f; for (int i = 0; i <= 5; ++i) { colors[i*4+0] = 0; colors[i*4+1] = 0; colors[i*4+2] = 0; colors[i*4+3] = (1.0 - brightness) * 65535.0f; } GLVertexBuffer *stream = GLVertexBuffer::streamingBuffer (); GLboolean glBlendEnabled = glIsEnabled (GL_BLEND); if (!glBlendEnabled) glEnable (GL_BLEND); stream->begin (GL_TRIANGLES); stream->addVertices (6, vertices); stream->addColors (6, colors); if (stream->end ()) stream->render (sTransform); /* only disable blending if it was already disabled */ if (!glBlendEnabled) glDisable (GL_BLEND); } if (!init && ps.active) ps.drawParticles (sTransform); } return status; }
bool ShowrepaintScreen::glPaintOutput (const GLScreenPaintAttrib &attrib, const GLMatrix &transform, const CompRegion ®ion, CompOutput *output, unsigned int mask) { bool status; GLMatrix sTransform; // initially identity matrix unsigned short color[4]; status = gScreen->glPaintOutput (attrib, transform, region, output, mask); tmpRegion = region.intersected (*output); if (tmpRegion.isEmpty ()) return status; sTransform.toScreenSpace (output, -DEFAULT_Z_CAMERA); color[3] = optionGetIntensity () * 0xffff / 100; color[0] = (rand () & 7) * color[3] / 8; color[1] = (rand () & 7) * color[3] / 8; color[2] = (rand () & 7) * color[3] / 8; GLboolean glBlendEnabled = glIsEnabled (GL_BLEND); if (!glBlendEnabled) glEnable (GL_BLEND); std::vector<GLfloat> vertices; /* for each rectangle, use two triangles to display it */ foreach (const CompRect &box, tmpRegion.rects ()) { //first triangle vertices.push_back (box.x1 ()); vertices.push_back (box.y1 ()); vertices.push_back (0.0f); vertices.push_back (box.x1 ()); vertices.push_back (box.y2 ()); vertices.push_back (0.0f); vertices.push_back (box.x2 ()); vertices.push_back (box.y2 ()); vertices.push_back (0.0f); //second triangle vertices.push_back (box.x2 ()); vertices.push_back (box.y2 ()); vertices.push_back (0.0f); vertices.push_back (box.x2 ()); vertices.push_back (box.y1 ()); vertices.push_back (0.0f); vertices.push_back (box.x1 ()); vertices.push_back (box.y1 ()); vertices.push_back (0.0f); } GLVertexBuffer *stream = GLVertexBuffer::streamingBuffer (); stream->begin (GL_TRIANGLES); stream->color4f ((float)color[0] / 65535.0f, (float)color[1] / 65535.0f, (float)color[2] / 65535.0f, (float)color[3] / 65535.0f); stream->addVertices (vertices.size () / 3, &vertices[0]); if (stream->end ()) stream->render (sTransform); stream->colorDefault (); /* only disable blending if it was disabled before */ if (!glBlendEnabled) glDisable (GL_BLEND); return status; }