Esempio n. 1
0
void
GLScreen::glBufferStencil (const GLMatrix       &matrix,
			   GLVertexBuffer       &vertexBuffer,
			   CompOutput           *output)
{
    WRAPABLE_HND_FUNCTN (glBufferStencil, matrix, vertexBuffer, output);

    GLfloat x = output->x ();
    GLfloat y = screen->height () - output->y2 ();
    GLfloat x2 = output->x () + output->width ();
    GLfloat y2 = screen->height () - output->y2 () + output->height ();

    GLfloat vertices[] =
    {
	x, y, 0,
	x, y2, 0,
	x2, y, 0,
	x2, y2, 0
    };

    GLushort colorData[] = { 0xffff, 0xffff, 0xffff, 0xffff };

    vertexBuffer.begin (GL_TRIANGLE_STRIP);

    vertexBuffer.addVertices (4, vertices);
    vertexBuffer.addColors (1, colorData);

    vertexBuffer.end ();
}
Esempio n. 2
0
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 ();
	    }
	}
    }
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
bool
FireScreen::glPaintOutput (const GLScreenPaintAttrib &attrib,
			   const GLMatrix            &transform,
			   const CompRegion          &region,
			   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;
}
Esempio n. 5
0
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);
}
Esempio n. 6
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
}