Exemple #1
0
CompRegion
CompRegion::xored (const CompRegion &r) const
{
    CompRegion rv;
    rv.priv->makeReal ();
    XXorRegion (handle (), r.handle (), rv.handle ());
    return rv;
}
Exemple #2
0
CompRegion
CompRegion::united (const CompRect &r) const
{
    CompRegion rv;
    rv.priv->makeReal ();
    XUnionRegion (handle (), r.region (), rv.handle ());
    return rv;
}
Exemple #3
0
CompRegion
CompRegion::subtracted (const CompRect &r) const
{
    CompRegion rv;
    rv.priv->makeReal ();
    XSubtractRegion (handle (), r.region (), rv.handle ());
    return rv;
}
Exemple #4
0
CompRegion
CompRegion::intersected (const CompRect &r) const
{
    CompRegion reg (r);
    reg.priv->makeReal ();
    XIntersectRegion (reg.handle (), handle (), reg.handle ());
    return reg;
}
bool
GLScreen::glPaintOutput (const GLScreenPaintAttrib &sAttrib,
			 const GLMatrix            &transform,
			 const CompRegion          &region,
			 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          &region,
				  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;
}
Exemple #7
0
CompPoint
compiz::wall::movementWindowOnScreen (const CompRect &serverBorderRect,
                                      const CompRegion &screenRegion)
{
    CompRegion sbrRegion (serverBorderRect);

    /* If the window would be partially offscreen
     * after it was moved then we should move it back
     * so that it is completely onscreen, since we moved
     * from mostly offscreen on B to mostly onscreen on A,
     * the user should be able to see their selected window */
    CompRegion inter = sbrRegion.intersected (screenRegion);
    CompRegion rem = sbrRegion - screenRegion;

    int dx = 0;
    int dy = 0;

    const CompRect::vector &rects (rem.rects ());

    for (std::vector <CompRect>::const_iterator it = rects.begin ();
            it != rects.end ();
            ++it)
    {
        const CompRect &r = *it;

        if (r.x1 () >= inter.boundingRect ().x2 ())
            dx -= r.width ();
        else if (r.x2 () <= inter.boundingRect ().x1 ())
            dx += r.width ();

        if (r.y1 () >= inter.boundingRect ().y2 ())
            dy -= r.height ();
        else if (r.y2 () <= inter.boundingRect ().y1 ())
            dy += r.height ();
    }

    return CompPoint (dx, dy);
}
void
GLWindow::glAddGeometry (const GLTexture::MatrixList &matrix,
			 const CompRegion            &region,
			 const CompRegion            &clip,
			 unsigned int                maxGridWidth,
			 unsigned int                maxGridHeight)
{
    WRAPABLE_HND_FUNCTN (glAddGeometry, matrix, region, clip)

    BoxRec full;
    int    nMatrix = matrix.size ();

    full = clip.handle ()->extents;
    if (region.handle ()->extents.x1 > full.x1)
	full.x1 = region.handle ()->extents.x1;
    if (region.handle ()->extents.y1 > full.y1)
	full.y1 = region.handle ()->extents.y1;
    if (region.handle ()->extents.x2 < full.x2)
	full.x2 = region.handle ()->extents.x2;
    if (region.handle ()->extents.y2 < full.y2)
	full.y2 = region.handle ()->extents.y2;

    if (full.x1 < full.x2 && full.y1 < full.y2)
    {
	BoxPtr  pBox;
	int     nBox;
	BoxPtr  pClip;
	int     nClip;
	BoxRec  cbox;
	int     it, x1, y1, x2, y2;
	bool    rect = true;

	for (it = 0; it < nMatrix; it++)
	{
	    if (matrix[it].xy != 0.0f || matrix[it].yx != 0.0f)
	    {
		rect = false;
		break;
	    }
	}

	pBox = const_cast <Region> (region.handle ())->rects;
	nBox = const_cast <Region> (region.handle ())->numRects;

	while (nBox--)
	{
	    x1 = pBox->x1;
	    y1 = pBox->y1;
	    x2 = pBox->x2;
	    y2 = pBox->y2;

	    pBox++;

	    if (x1 < full.x1)
		x1 = full.x1;
	    if (y1 < full.y1)
		y1 = full.y1;
	    if (x2 > full.x2)
		x2 = full.x2;
	    if (y2 > full.y2)
		y2 = full.y2;

	    if (x1 < x2 && y1 < y2)
	    {
		nClip = const_cast <Region> (clip.handle ())->numRects;

		if (nClip == 1)
		{
		    addQuads (priv->vertexBuffer, matrix, nMatrix,
			      x1, y1, x2, y2,
			      rect,
			      maxGridWidth, maxGridHeight);
		}
		else
		{
		    pClip = const_cast <Region> (clip.handle ())->rects;

		    while (nClip--)
		    {
			cbox = *pClip;

			pClip++;

			if (cbox.x1 < x1)
			    cbox.x1 = x1;
			if (cbox.y1 < y1)
			    cbox.y1 = y1;
			if (cbox.x2 > x2)
			    cbox.x2 = x2;
			if (cbox.y2 > y2)
			    cbox.y2 = y2;

			if (cbox.x1 < cbox.x2 && cbox.y1 < cbox.y2)
			{
			    addQuads (priv->vertexBuffer, matrix, nMatrix,
				      cbox.x1, cbox.y1, cbox.x2, cbox.y2,
				      rect,
				      maxGridWidth, maxGridHeight);
			}
		    }
		}
	    }
	}
    }
}
void
PrivateGLScreen::paintBackground (const GLMatrix   &transform,
                                  const CompRegion &region,
				  bool             transformed)
{
    GLVertexBuffer *streamingBuffer = GLVertexBuffer::streamingBuffer ();
    GLfloat         vertexData[18];
    GLushort        colorData[4];

    BoxPtr    pBox = const_cast <Region> (region.handle ())->rects;
    int	      n, nBox = const_cast <Region> (region.handle ())->numRects;

    if (!nBox)
	return;

    if (screen->desktopWindowCount ())
    {
	if (!backgroundTextures.empty ())
	{
	    backgroundTextures.clear ();
	}

	backgroundLoaded = false;

	return;
    }
    else
    {
	if (!backgroundLoaded)
	    updateScreenBackground ();

	backgroundLoaded = true;
    }

    if (backgroundTextures.empty ())
    {
	streamingBuffer->begin (GL_TRIANGLES);
	n = nBox;

	while (n--)
	{
	    vertexData[0]  = pBox->x1;
	    vertexData[1]  = pBox->y1;
	    vertexData[2]  = 0.0f;
	    vertexData[3]  = pBox->x1;
	    vertexData[4]  = pBox->y2;
	    vertexData[5]  = 0.0f;
	    vertexData[6]  = pBox->x2;
	    vertexData[7]  = pBox->y1;
	    vertexData[8]  = 0.0f;
	    vertexData[9]  = pBox->x1;
	    vertexData[10] = pBox->y2;
	    vertexData[11] = 0.0f;
	    vertexData[12] = pBox->x2;
	    vertexData[13] = pBox->y2;
	    vertexData[14] = 0.0f;

	    vertexData[15] = pBox->x2;
	    vertexData[16] = pBox->y1;
	    vertexData[17] = 0.0f;

	    streamingBuffer->addVertices (6, vertexData);

	    pBox++;
	}

	colorData[0] = colorData[1] = colorData[2] = 0;
	colorData[3] = std::numeric_limits <unsigned short>::max ();
	streamingBuffer->addColors (1, colorData);

	streamingBuffer->end ();
	streamingBuffer->render (transform);
    }
    else
    {
	n = nBox;

	for (unsigned int i = 0; i < backgroundTextures.size (); i++)
	{
	    GLfloat textureData[12];
	    GLTexture *bg = backgroundTextures[i];
	    CompRegion r = region & *bg;

	    pBox = const_cast <Region> (r.handle ())->rects;
	    nBox = const_cast <Region> (r.handle ())->numRects;
	    n = nBox;

	    streamingBuffer->begin (GL_TRIANGLES);

	    while (n--)
	    {
		GLfloat tx1 = COMP_TEX_COORD_X (bg->matrix (), pBox->x1);
		GLfloat tx2 = COMP_TEX_COORD_X (bg->matrix (), pBox->x2);
		GLfloat ty1 = COMP_TEX_COORD_Y (bg->matrix (), pBox->y1);
		GLfloat ty2 = COMP_TEX_COORD_Y (bg->matrix (), pBox->y2);

		vertexData[0]  = pBox->x1;
		vertexData[1]  = pBox->y1;
		vertexData[2]  = 0.0f;
		vertexData[3]  = pBox->x1;
		vertexData[4]  = pBox->y2;
		vertexData[5]  = 0.0f;
		vertexData[6]  = pBox->x2;
		vertexData[7]  = pBox->y1;
		vertexData[8]  = 0.0f;
		vertexData[9]  = pBox->x1;
		vertexData[10] = pBox->y2;
		vertexData[11] = 0.0f;
		vertexData[12] = pBox->x2;
		vertexData[13] = pBox->y2;
		vertexData[14] = 0.0f;

		vertexData[15] = pBox->x2;
		vertexData[16] = pBox->y1;
		vertexData[17] = 0.0f;

		textureData[0]  = tx1;
		textureData[1]  = ty1;

		textureData[2]  = tx1;
		textureData[3]  = ty2;

		textureData[4]  = tx2;
		textureData[5]  = ty1;

		textureData[6]  = tx1;
		textureData[7]  = ty2;

		textureData[8]  = tx2;
		textureData[9]  = ty2;

		textureData[10] = tx2;
		textureData[11] = ty1;

		streamingBuffer->addVertices (6, vertexData);
		streamingBuffer->addTexCoords (0, 6, textureData);

		pBox++;
	    }

	    streamingBuffer->end ();

	    if (bg->name ())
	    {
		if (transformed)
		    bg->enable (GLTexture::Good);
		else
		    bg->enable (GLTexture::Fast);

		streamingBuffer->render (transform);

		bg->disable ();
	    }
	}
    }
}
Exemple #10
0
void
GLScreen::glPaintCompositedOutput (const CompRegion    &region,
				   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 ();
}
Exemple #11
0
void
GridAnim::addGeometry (const GLTexture::MatrixList &matrix,
		       const CompRegion            &region,
		       const CompRegion            &clip,
		       unsigned int                maxGridWidth,
		       unsigned int                maxGridHeight)
{
    if (region.isEmpty ()) // nothing to do
	return;

    GLfloat *v, *vMax;
    bool notUsing3dCoords = !using3D ();

    CompRect outRect (mAWindow->savedRectsValid () ?
		      mAWindow->savedOutRect () :
		      mWindow->outputRect ());
    CompWindowExtents outExtents (mAWindow->savedRectsValid () ?
				  mAWindow->savedOutExtents () :
				  mWindow->output ());

    // window output (contents + decorations + shadows) coordinates and size
    int ox = outRect.x ();
    int oy = outRect.y ();
    int owidth = outRect.width ();
    int oheight = outRect.height ();

    // to be used if event is shade/unshade
    float winContentsY = oy + outExtents.top;
    float winContentsHeight = oheight - outExtents.top - outExtents.bottom;

    GLWindow *gWindow = GLWindow::get (mWindow);
    GLVertexBuffer *vertexBuffer = gWindow->vertexBuffer ();
    int vSize = vertexBuffer->getVertexStride ();

    // Indentation kept to provide a clean diff with the old code, for now...
    {
	int y1 = outRect.y1 ();
	int x2 = outRect.x2 ();
	int y2 = outRect.y2 ();

	float gridW = (float)owidth / (mGridWidth - 1);
	float gridH;

	if (mCurWindowEvent == WindowEventShade ||
	    mCurWindowEvent == WindowEventUnshade)
	{
	    if (y1 < winContentsY)	// if at top part
		gridH = mDecorTopHeight;
	    else if (y2 > winContentsY + winContentsHeight)  // if at bottom
		gridH = mDecorBottomHeight;
	    else			// in window contents (only in Y coords)
	    {
		float winContentsHeight =
		    oheight - (mDecorTopHeight + mDecorBottomHeight);
		gridH = winContentsHeight / (mGridHeight - 3);
	    }
	}
	else
	    gridH = (float)oheight / (mGridHeight - 1);

	int oldCount = vertexBuffer->countVertices ();
	gWindow->glAddGeometry (matrix, region, clip, gridW, gridH);
	int newCount = vertexBuffer->countVertices ();
	v = vertexBuffer->getVertices () + (oldCount * vSize);
	vMax = vertexBuffer->getVertices () + (newCount * vSize);
 
	float x, y, topiyFloat;
	// For each vertex
	for (; v < vMax; v += vSize)
	{
	    x = v[0];
	    y = v[1];

	    if (y > y2)
		y = y2;

	    if (mCurWindowEvent == WindowEventShade ||
		mCurWindowEvent == WindowEventUnshade)
	    {
		if (y1 < winContentsY)	// if at top part
		{
		    topiyFloat = (y - oy) / mDecorTopHeight;
		    topiyFloat = MIN (topiyFloat, 0.999);	// avoid 1.0
		}
		else if (y2 > winContentsY + winContentsHeight)	// if at bottom
		    topiyFloat = (mGridHeight - 2) +
			(mDecorBottomHeight ? (y - winContentsY -
					       winContentsHeight) /
			 mDecorBottomHeight : 0);
		else		// in window contents (only in Y coords)
		    topiyFloat = (mGridHeight - 3) *
			(y - winContentsY) / winContentsHeight + 1;
	    }
	    else
		topiyFloat = (mGridHeight - 1) * (y - oy) / oheight;

	    // topiy should be at most (mGridHeight - 2)
	    int topiy = (int)(topiyFloat + 1e-4);

	    if (topiy == mGridHeight - 1)
		--topiy;

	    int   bottomiy = topiy + 1;
	    float iny      = topiyFloat - topiy;
	    float inyRest  = 1 - iny;

	    // End of calculations for y

	    // Indentation kept to provide a clean diff with the old code...
	    {
		if (x > x2)
		    x = x2;

		// find containing grid cell (leftix rightix) x (topiy bottomiy)
		float leftixFloat = (mGridWidth - 1) * (x - ox) / owidth;
		int leftix = (int)(leftixFloat + 1e-4);

		if (leftix == mGridWidth - 1)
		    --leftix;

		int rightix = leftix + 1;

		// GridModel::GridObjects that are at top, bottom, left, right corners of quad
		GridModel::GridObject *objToTopLeft =
		    &(mModel->mObjects[topiy * mGridWidth + leftix]);
		GridModel::GridObject *objToTopRight =
		    &(mModel->mObjects[topiy * mGridWidth + rightix]);
		GridModel::GridObject *objToBottomLeft =
		    &(mModel->mObjects[bottomiy * mGridWidth + leftix]);
		GridModel::GridObject *objToBottomRight =
		    &(mModel->mObjects[bottomiy * mGridWidth + rightix]);

		Point3d &objToTopLeftPos = objToTopLeft->mPosition;
		Point3d &objToTopRightPos = objToTopRight->mPosition;
		Point3d &objToBottomLeftPos = objToBottomLeft->mPosition;
		Point3d &objToBottomRightPos = objToBottomRight->mPosition;

		// find position in cell by taking remainder of flooring
		float inx = leftixFloat - leftix;
		float inxRest = 1 - inx;

		// Interpolate to find deformed coordinates

		float hor1x = (inxRest * objToTopLeftPos.x () +
			       inx * objToTopRightPos.x ());
		float hor1y = (inxRest * objToTopLeftPos.y () +
			       inx * objToTopRightPos.y ());
		float hor1z = (notUsing3dCoords ? 0 :
			       inxRest * objToTopLeftPos.z () +
			       inx * objToTopRightPos.z ());
		float hor2x = (inxRest * objToBottomLeftPos.x () +
			       inx * objToBottomRightPos.x ());
		float hor2y = (inxRest * objToBottomLeftPos.y () +
			       inx * objToBottomRightPos.y ());
		float hor2z = (notUsing3dCoords ? 0 :
			       inxRest * objToBottomLeftPos.z () +
			       inx * objToBottomRightPos.z ());

		float deformedX = inyRest * hor1x + iny * hor2x;
		float deformedY = inyRest * hor1y + iny * hor2y;
		float deformedZ = inyRest * hor1z + iny * hor2z;

		v[0] = deformedX;
		v[1] = deformedY;
		v[2] = deformedZ;

	    }
	}
    }
}
Exemple #12
0
bool
ShowrepaintScreen::glPaintOutput (const GLScreenPaintAttrib &attrib,
				  const GLMatrix            &transform,
				  const CompRegion          &region,
				  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;
}
Exemple #13
0
void
GridAnim::addGeometry (const GLTexture::MatrixList &matrix,
		       const CompRegion            &region,
		       const CompRegion            &clip,
		       unsigned int                maxGridWidth,
		       unsigned int                maxGridHeight)
{
    unsigned int nMatrix = matrix.size ();
    int nVertices, nIndices;
    GLushort *i;
    GLfloat *v;
    int x1, y1, x2, y2;
    float winContentsY, winContentsHeight;
    float deformedX, deformedY;
    float deformedZ = 0;
    int nVertX, nVertY;
    int vSize;
    float gridW, gridH;
    bool rect = true;
    bool notUsing3dCoords = !using3D ();

    if (region.isEmpty ()) // nothing to do
	return;

    GLWindow::Geometry &geometry = GLWindow::get (mWindow)->geometry ();

    for (unsigned int it = 0; it < nMatrix; it++)
    {
	if (matrix[it].xy != 0.0f || matrix[it].yx != 0.0f)
	{
	    rect = false;
	    break;
	}
    }

    CompRect outRect (mAWindow->savedRectsValid () ?
		      mAWindow->savedOutRect () :
		      mWindow->outputRect ());
    CompWindowExtents outExtents (mAWindow->savedRectsValid () ?
				  mAWindow->savedOutExtents () :
				  mWindow->output ());

    // window output (contents + decorations + shadows) coordinates and size
    int ox = outRect.x ();
    int oy = outRect.y ();
    int owidth = outRect.width ();
    int oheight = outRect.height ();

    // to be used if event is shade/unshade
    winContentsY = oy + outExtents.top;
    winContentsHeight = oheight - outExtents.top - outExtents.bottom;

    geometry.texUnits = (int)nMatrix;

    if (geometry.vCount == 0)
    {
	// reset
	geometry.indexCount = 0;
	geometry.texCoordSize = 4;
    }
    geometry.vertexStride = 3 + geometry.texUnits * geometry.texCoordSize;
    vSize = geometry.vertexStride;

    nVertices = geometry.vCount;
    nIndices = geometry.indexCount;

    v = geometry.vertices + (nVertices * vSize);
    i = geometry.indices + nIndices;

    // For each clip passed to this function
    foreach (const CompRect &pClip, region.rects ())
    {
	x1 = pClip.x1 ();
	y1 = pClip.y1 ();
	x2 = pClip.x2 ();
	y2 = pClip.y2 ();

	gridW = (float)owidth / (mGridWidth - 1);

	if (mCurWindowEvent == WindowEventShade ||
	    mCurWindowEvent == WindowEventUnshade)
	{
	    if (y1 < winContentsY)	// if at top part
	    {
		gridH = mDecorTopHeight;
	    }
	    else if (y2 > winContentsY + winContentsHeight)  // if at bottom
	    {
		gridH = mDecorBottomHeight;
	    }
	    else			// in window contents (only in Y coords)
	    {
		float winContentsHeight =
		    oheight - (mDecorTopHeight + mDecorBottomHeight);
		gridH = winContentsHeight / (mGridHeight - 3);
	    }
	}
	else
	    gridH = (float)oheight / (mGridHeight - 1);

	// nVertX, nVertY: number of vertices for this clip in x and y dimensions
	// + 2 to avoid running short of vertices in some cases
	nVertX = ceil ((x2 - x1) / gridW) + 2;
	nVertY = (gridH ? ceil ((y2 - y1) / gridH) : 0) + 2;

	// Allocate 4 indices for each quad
	int newIndexSize = nIndices + ((nVertX - 1) * (nVertY - 1) * 4);

	if (newIndexSize > geometry.indexSize)
	{
	    if (!geometry.moreIndices (newIndexSize))
		return;

	    i = geometry.indices + nIndices;
	}
	// Assign quad vertices to indices
	for (int jy = 0; jy < nVertY - 1; jy++)
	{
	    for (int jx = 0; jx < nVertX - 1; jx++)
	    {
		*i++ = nVertices + nVertX * (2 * jy + 1) + jx;
		*i++ = nVertices + nVertX * (2 * jy + 1) + jx + 1;
		*i++ = nVertices + nVertX * 2 * jy + jx + 1;
		*i++ = nVertices + nVertX * 2 * jy + jx;

		nIndices += 4;
	    }
	}

	// Allocate vertices
	int newVertexSize =
	    (nVertices + nVertX * (2 * nVertY - 2)) * vSize;
	if (newVertexSize > geometry.vertexSize)
	{
	    if (!geometry.moreVertices (newVertexSize))
		return;

	    v = geometry.vertices + (nVertices * vSize);
	}

	float rowTexCoordQ = 1;
	float prevRowCellWidth = 0;	// this initial value won't be used
	float rowCellWidth = 0;
	int clipRowSize = nVertX * vSize;

	// For each vertex
	float y = y1;
	for (int jy = 0; jy < nVertY; jy++)
	{
	    float topiyFloat;
	    bool applyOffsets = true;

	    if (y > y2)
		y = y2;

	    // Do calculations for y here to avoid repeating
	    // them unnecessarily in the x loop

	    if (mCurWindowEvent == WindowEventShade ||
		mCurWindowEvent == WindowEventUnshade)
	    {
		if (y1 < winContentsY)	// if at top part
		{
		    topiyFloat = (y - oy) / mDecorTopHeight;
		    topiyFloat = MIN (topiyFloat, 0.999);	// avoid 1.0
		    applyOffsets = false;
		}
		else if (y2 > winContentsY + winContentsHeight)	// if at bottom
		{
		    topiyFloat = (mGridHeight - 2) +
			(mDecorBottomHeight ? (y - winContentsY -
					       winContentsHeight) /
			 mDecorBottomHeight : 0);
		    applyOffsets = false;
		}
		else		// in window contents (only in Y coords)
		{
		    topiyFloat = (mGridHeight - 3) *
			(y - winContentsY) / winContentsHeight + 1;
		}
	    }
	    else
	    {
		topiyFloat = (mGridHeight - 1) * (y - oy) / oheight;
	    }
	    // topiy should be at most (mGridHeight - 2)
	    int topiy = (int)(topiyFloat + 1e-4);

	    if (topiy == mGridHeight - 1)
		topiy--;
	    int bottomiy = topiy + 1;
	    float iny = topiyFloat - topiy;
	    float inyRest = 1 - iny;

	    // End of calculations for y

	    float x = x1;
	    for (int jx = 0; jx < nVertX; jx++)
	    {
		if (x > x2)
		    x = x2;

		// find containing grid cell (leftix rightix) x (topiy bottomiy)
		float leftixFloat =
		    (mGridWidth - 1) * (x - ox) / owidth;
		int leftix = (int)(leftixFloat + 1e-4);

		if (leftix == mGridWidth - 1)
		    leftix--;
		int rightix = leftix + 1;

		// GridModel::GridObjects that are at top, bottom, left, right corners of quad
		GridModel::GridObject *objToTopLeft =
		    &(mModel->mObjects[topiy * mGridWidth + leftix]);
		GridModel::GridObject *objToTopRight =
		    &(mModel->mObjects[topiy * mGridWidth + rightix]);
		GridModel::GridObject *objToBottomLeft =
		    &(mModel->mObjects[bottomiy * mGridWidth + leftix]);
		GridModel::GridObject *objToBottomRight =
		    &(mModel->mObjects[bottomiy * mGridWidth + rightix]);

		Point3d &objToTopLeftPos = objToTopLeft->mPosition;
		Point3d &objToTopRightPos = objToTopRight->mPosition;
		Point3d &objToBottomLeftPos = objToBottomLeft->mPosition;
		Point3d &objToBottomRightPos = objToBottomRight->mPosition;

		// find position in cell by taking remainder of flooring
		float inx = leftixFloat - leftix;
		float inxRest = 1 - inx;

		// Interpolate to find deformed coordinates

		float hor1x = (inxRest * objToTopLeftPos.x () +
			       inx * objToTopRightPos.x ());
		float hor1y = (inxRest * objToTopLeftPos.y () +
			       inx * objToTopRightPos.y ());
		float hor1z = (notUsing3dCoords ? 0 :
			       inxRest * objToTopLeftPos.z () +
			       inx * objToTopRightPos.z ());
		float hor2x = (inxRest * objToBottomLeftPos.x () +
			       inx * objToBottomRightPos.x ());
		float hor2y = (inxRest * objToBottomLeftPos.y () +
			       inx * objToBottomRightPos.y ());
		float hor2z = (notUsing3dCoords ? 0 :
			       inxRest * objToBottomLeftPos.z () +
			       inx * objToBottomRightPos.z ());

		deformedX = inyRest * hor1x + iny * hor2x;
		deformedY = inyRest * hor1y + iny * hor2y;
		deformedZ = inyRest * hor1z + iny * hor2z;

		// Texture coordinates (s, t, r, q)

		if (mUseQTexCoord)
		{
		    if (jx == 1)
			rowCellWidth = deformedX - v[-3];

		    // do only once per row for all rows except row 0
		    if (jy > 0 && jx == 1)
		    {
			rowTexCoordQ = (rowCellWidth / prevRowCellWidth);

			for (unsigned int it = 0; it < nMatrix; it++, v += 4)
			{
			    // update first column
			    // (since we didn't know rowTexCoordQ before)
			    v[-vSize]     *= rowTexCoordQ; // multiply s & t by q
			    v[-vSize + 1] *= rowTexCoordQ;
			    v[-vSize + 3] = rowTexCoordQ;  // copy q
			}
			v -= nMatrix * 4;
		    }
		}

		// Loop for each texture element
		// (4 texture coordinates for each one)
		for (unsigned int it = 0; it < nMatrix; it++, v += 4)
		{
		    float offsetY = 0;

		    if (rect)
		    {
			if (applyOffsets && y < y2)
			    offsetY = objToTopLeft->mOffsetTexCoordForQuadAfter.y ();
			v[0] = COMP_TEX_COORD_X (matrix[it], x); // s
			v[1] = COMP_TEX_COORD_Y (matrix[it], y + offsetY); // t
		    }
		    else
		    {
			if (applyOffsets && y < y2)
			    // FIXME:
			    // The correct y offset below produces wrong
			    // texture coordinates for some reason.
			    offsetY = 0;
			    // offsetY = objToTopLeft->offsetTexCoordForQuadAfter.y;
			v[0] = COMP_TEX_COORD_XY (matrix[it], x, y + offsetY); // s
			v[1] = COMP_TEX_COORD_YX (matrix[it], x, y + offsetY); // t
		    }
		    v[2] = 0; // r

		    if (0 < jy && jy < nVertY - 1)
		    {
			// copy s, t, r to duplicate row
			memcpy (v + clipRowSize, v, 3 * sizeof (GLfloat));
			v[3 + clipRowSize] = 1; // q
		    }

		    if (applyOffsets &&
			objToTopLeft->mOffsetTexCoordForQuadBefore.y () != 0)
		    {
			// After copying to next row, update texture y coord
			// by following object's offset
			offsetY = objToTopLeft->mOffsetTexCoordForQuadBefore.y ();
			if (rect)
			{
			    v[1] = COMP_TEX_COORD_Y (matrix[it], y + offsetY);
			}
			else
			{
			    v[0] = COMP_TEX_COORD_XY (matrix[it],
						      x, y + offsetY);
			    v[1] = COMP_TEX_COORD_YX (matrix[it],
						      x, y + offsetY);
			}
		    }
		    if (mUseQTexCoord)
		    {
			v[3] = rowTexCoordQ; // q

			if (jx > 0)	// since column 0 is updated when jx == 1
			{
			    // multiply s & t by q
			    v[0] *= rowTexCoordQ;
			    v[1] *= rowTexCoordQ;
			}
		    }
		    else
		    {
			v[3] = 1; // q
		    }
		}

		v[0] = deformedX;
		v[1] = deformedY;
		v[2] = deformedZ;

		// Copy vertex coordinates to duplicate row
		if (0 < jy && jy < nVertY - 1)
		    memcpy (v + clipRowSize, v, 3 * sizeof (GLfloat));

		nVertices++;

		// increment x properly (so that coordinates fall on grid intersections)
		x = rightix * gridW + ox;

		v += 3; // move on to next vertex
	    }
	    if (mUseQTexCoord)
		prevRowCellWidth = rowCellWidth;

	    if (0 < jy && jy < nVertY - 1)
	    {
		v += clipRowSize;	// skip the duplicate row
		nVertices += nVertX;
	    }
	    // increment y properly (so that coordinates fall on grid intersections)
	    if (mCurWindowEvent == WindowEventShade ||
		mCurWindowEvent == WindowEventUnshade)
	    {
		y += gridH;
	    }
	    else
	    {
		y = bottomiy * gridH + oy;
	    }
	}
    }
    geometry.vCount = nVertices;
    geometry.indexCount = nIndices;
}
Exemple #14
0
bool
CompRegion::operator== (const CompRegion &c) const
{
    return XEqualRegion (handle (), c.handle ());
}