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 ();
	    }
	}
    }
}
void
ParticleSystem::drawParticles(const GLMatrix &transform)
{
    int i, j, k, l;

    /* Check that the cache is big enough */
    if (vertices_cache.size () < particles.size () * VERTEX_COMPONENTS)
	vertices_cache.resize (particles.size () * VERTEX_COMPONENTS);

    if (coords_cache.size () < particles.size () * COORD_COMPONENTS)
	coords_cache.resize (particles.size () * COORD_COMPONENTS);

    if (colors_cache.size () < particles.size () * COLOR_COMPONENTS)
	colors_cache.resize (particles.size () * COLOR_COMPONENTS);

    if (darken > 0)
	if (dcolors_cache.size () < particles.size () * COLOR_COMPONENTS)
	    dcolors_cache.resize (particles.size () * COLOR_COMPONENTS);

    GLboolean glBlendEnabled = glIsEnabled (GL_BLEND);

    if (!glBlendEnabled)
	glEnable (GL_BLEND);

    if (tex)
    {
	glBindTexture (GL_TEXTURE_2D, tex);
	glEnable (GL_TEXTURE_2D);
    }

    i = j = k = l = 0;

    GLfloat w, h;
    GLfloat xMinusW, xPlusW, yMinusH, yPlusH;
    GLushort r, g, b, a, dark_a;

    /* for each particle, use two triangles to display it */
    foreach (Particle &part, particles) 
    {
	if (part.life > 0.0f)
	{
	    w = part.width  / 2.0f;
	    h = part.height / 2.0f;

	    r = part.r * 65535.0f;
	    g = part.g * 65535.0f;
	    b = part.b * 65535.0f;
	    a      = part.life * part.a * 65535.0f;
	    dark_a = part.life * part.a * 65535.0f * darken;

	    w += w * part.w_mod * part.life;
	    h += h * part.h_mod * part.life;

	    xMinusW = part.x - w;
	    xPlusW  = part.x + w;

	    yMinusH = part.y - h;
	    yPlusH  = part.y + h;

	    //first triangle
	    vertices_cache[i + 0] = xMinusW;
	    vertices_cache[i + 1] = yMinusH;
	    vertices_cache[i + 2] = part.z;

	    vertices_cache[i + 3] = xMinusW;
	    vertices_cache[i + 4] = yPlusH;
	    vertices_cache[i + 5] = part.z;

	    vertices_cache[i + 6] = xPlusW;
	    vertices_cache[i + 7] = yPlusH;
	    vertices_cache[i + 8] = part.z;

	    //second triangle
	    vertices_cache[i + 9]  = xPlusW;
	    vertices_cache[i + 10] = yPlusH;
	    vertices_cache[i + 11] = part.z;

	    vertices_cache[i + 12] = xPlusW;
	    vertices_cache[i + 13] = yMinusH;
	    vertices_cache[i + 14] = part.z;

	    vertices_cache[i + 15] = xMinusW;
	    vertices_cache[i + 16] = yMinusH;
	    vertices_cache[i + 17] = part.z;

	    i += 18;

	    coords_cache[j + 0] = 0.0;
	    coords_cache[j + 1] = 0.0;

	    coords_cache[j + 2] = 0.0;
	    coords_cache[j + 3] = 1.0;

	    coords_cache[j + 4] = 1.0;
	    coords_cache[j + 5] = 1.0;

	    //second
	    coords_cache[j + 6] = 1.0;
	    coords_cache[j + 7] = 1.0;

	    coords_cache[j + 8] = 1.0;
	    coords_cache[j + 9] = 0.0;
	    
	    coords_cache[j + 10] = 0.0;
	    coords_cache[j + 11] = 0.0;

	    j += 12;

	    colors_cache[k + 0] = r;
	    colors_cache[k + 1] = g;
	    colors_cache[k + 2] = b;
	    colors_cache[k + 3] = a;

	    colors_cache[k + 4] = r;
	    colors_cache[k + 5] = g;
	    colors_cache[k + 6] = b;
	    colors_cache[k + 7] = a;

	    colors_cache[k + 8]  = r;
	    colors_cache[k + 9]  = g;
	    colors_cache[k + 10] = b;
	    colors_cache[k + 11] = a;

	    //second
	    colors_cache[k + 12] = r;
	    colors_cache[k + 13] = g;
	    colors_cache[k + 14] = b;
	    colors_cache[k + 15] = a;

	    colors_cache[k + 16] = r;
	    colors_cache[k + 17] = g;
	    colors_cache[k + 18] = b;
	    colors_cache[k + 19] = a;

	    colors_cache[k + 20] = r;
	    colors_cache[k + 21] = g;
	    colors_cache[k + 22] = b;
	    colors_cache[k + 23] = a;

	    k += 24;

	    if (darken > 0)
	    {
		dcolors_cache[l + 0] = r;
		dcolors_cache[l + 1] = g;
		dcolors_cache[l + 2] = b;
		dcolors_cache[l + 3] = dark_a;

		dcolors_cache[l + 4] = r;
		dcolors_cache[l + 5] = g;
		dcolors_cache[l + 6] = b;
		dcolors_cache[l + 7] = dark_a;

		dcolors_cache[l + 8]  = r;
		dcolors_cache[l + 9]  = g;
		dcolors_cache[l + 10] = b;
		dcolors_cache[l + 11] = dark_a;

		//second
		dcolors_cache[l + 12] = r;
		dcolors_cache[l + 13] = g;
		dcolors_cache[l + 14] = b;
		dcolors_cache[l + 15] = dark_a;

		dcolors_cache[l + 16] = r;
		dcolors_cache[l + 17] = g;
		dcolors_cache[l + 18] = b;
		dcolors_cache[l + 19] = dark_a;

		dcolors_cache[l + 20] = r;
		dcolors_cache[l + 21] = g;
		dcolors_cache[l + 22] = b;
		dcolors_cache[l + 23] = dark_a;

		l += 24;
	    }
	}
    }

    GLVertexBuffer *stream = GLVertexBuffer::streamingBuffer ();

    if (darken > 0)
    {
	glBlendFunc (GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
	stream->begin (GL_TRIANGLES);
	stream->addVertices (i / 3, &vertices_cache[0]);
	stream->addTexCoords (0, j / 2, &coords_cache[0]);
	stream->addColors (l / 4, &dcolors_cache[0]);

	if (stream->end ())
	    stream->render (transform);
    }

    /* draw particles */
    glBlendFunc (GL_SRC_ALPHA, blendMode);
    stream->begin (GL_TRIANGLES);

    stream->addVertices (i / 3, &vertices_cache[0]);
    stream->addTexCoords (0, j / 2, &coords_cache[0]);
    stream->addColors (k / 4, &colors_cache[0]);

    if (stream->end ())
	stream->render (transform);

    glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
    glDisable (GL_TEXTURE_2D);

    /* only disable blending if it was disabled before */
    if (!glBlendEnabled)
	glDisable (GL_BLEND);
}
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 #4
0
void
CompText::draw (const GLMatrix &transform,
                float           x,
	        float y,
	        float alpha) const
{
    GLint      oldBlendSrc, oldBlendDst;
    GLushort        colorData[4];
    GLfloat         textureData[8];
    GLfloat         vertexData[12];
    GLVertexBuffer *streamingBuffer = GLVertexBuffer::streamingBuffer ();

    if (texture.empty ())
	return;

#ifdef USE_GLES
    GLint           oldBlendSrcAlpha, oldBlendDstAlpha;
    glGetIntegerv (GL_BLEND_SRC_RGB, &oldBlendSrc);
    glGetIntegerv (GL_BLEND_DST_RGB, &oldBlendDst);
    glGetIntegerv (GL_BLEND_SRC_ALPHA, &oldBlendSrcAlpha);
    glGetIntegerv (GL_BLEND_DST_ALPHA, &oldBlendDstAlpha);
#else
    glGetIntegerv (GL_BLEND_SRC, &oldBlendSrc);
    glGetIntegerv (GL_BLEND_DST, &oldBlendDst);

    GLboolean  wasBlend;
    wasBlend = glIsEnabled (GL_BLEND);
    if (!wasBlend)
	glEnable (GL_BLEND);
#endif

    glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

    colorData[0] = alpha * 65535;
    colorData[1] = alpha * 65535;
    colorData[2] = alpha * 65535;
    colorData[3] = alpha * 65535;

    for (unsigned int i = 0; i < texture.size (); i++)
    {
	GLTexture         *tex = texture[i];
	GLTexture::Matrix m = tex->matrix ();

	tex->enable (GLTexture::Good);

	streamingBuffer->begin (GL_TRIANGLE_STRIP);

	vertexData[0]  = x;
	vertexData[1]  = y - height;
	vertexData[2]  = 0;
	vertexData[3]  = x;
	vertexData[4]  = y;
	vertexData[5]  = 0;
	vertexData[6]  = x + width;
	vertexData[7]  = y - height;
	vertexData[8]  = 0;
	vertexData[9]  = x + width;
	vertexData[10] = y;
	vertexData[11] = 0;

	textureData[0] = COMP_TEX_COORD_X (m, 0);
	textureData[1] = COMP_TEX_COORD_Y (m, 0);
	textureData[2] = COMP_TEX_COORD_X (m, 0);
	textureData[3] = COMP_TEX_COORD_Y (m, height);
	textureData[4] = COMP_TEX_COORD_X (m, width);
	textureData[5] = COMP_TEX_COORD_Y (m, 0);
	textureData[6] = COMP_TEX_COORD_X (m, width);
	textureData[7] = COMP_TEX_COORD_Y (m, height);

	streamingBuffer->addColors (1, colorData);
	streamingBuffer->addVertices (4, vertexData);
	streamingBuffer->addTexCoords (0, 4, textureData);

	streamingBuffer->end ();
	streamingBuffer->render (transform);

	tex->disable ();
    }

#ifdef USE_GLES
    glBlendFuncSeparate (oldBlendSrc, oldBlendDst,
                         oldBlendSrcAlpha, oldBlendDstAlpha);
#else
    if (!wasBlend)
	glDisable (GL_BLEND);
    glBlendFunc (oldBlendSrc, oldBlendDst);
#endif
}