void PrivateGLScreen::paintBackground (const GLMatrix &transform, const CompRegion ®ion, 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 ®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 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 }