GLMatrix inverse( const GLMatrix & mat ) { GLMatrix result; GLfloat d = det(mat); if (fabs(d) < 0.0005) { result.setIdentity(); } else { d = 1.0f/d; result.data[0] = (mat.data[5] * mat.data[10] - mat.data[6] * mat.data[9]) * d; result.data[1] = -(mat.data[1] * mat.data[10] - mat.data[9] * mat.data[2]) * d; result.data[2] = (mat.data[1] * mat.data[6] - mat.data[5] * mat.data[2]) * d; result.data[3] = -(mat.data[4] * mat.data[10] - mat.data[6] * mat.data[8]) * d; result.data[4] = (mat.data[0] * mat.data[10] - mat.data[2] * mat.data[8]) * d; result.data[5] = -(mat.data[0] * mat.data[6] - mat.data[2] * mat.data[4]) * d; result.data[6] = (mat.data[4] * mat.data[9] - mat.data[5] * mat.data[8]) * d; result.data[7] = -(mat.data[0] * mat.data[9] - mat.data[1] * mat.data[8]) * d; result.data[8] = (mat.data[0] * mat.data[5] - mat.data[1] * mat.data[4]) * d; } return result; }
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; } }
void ExpandAnim::applyTransform () { GLMatrix *transform = &mTransform; float defaultXScale = 0.3f; float forwardProgress; float expandProgress; const float expandPhaseEnd = 0.5f; forwardProgress = getProgress (); if ((1 - forwardProgress) < expandPhaseEnd) expandProgress = (1 - forwardProgress) / expandPhaseEnd; else expandProgress = 1.0f; // animation movement transform->translate (WIN_X (mWindow) + WIN_W (mWindow) / 2.0f, WIN_Y (mWindow) + WIN_H (mWindow) / 2.0f, 0.0f); transform->scale (defaultXScale + (1.0f - defaultXScale) * expandProgress, (1 - forwardProgress), 0.0f); transform->translate (-(WIN_X (mWindow) + WIN_W (mWindow) / 2.0f), -(WIN_Y (mWindow) + WIN_H (mWindow) / 2.0f), 0.0f); }
bool GLCamera::RotCamBase(double angle) { GLVertex3 org; GLMatrix mx = fCamBase*fCamTrans; GLVector3 fwd = mx.GetBaseVec(1); fCamBase.Rotate(org, fwd, angle); return (angle != 0); }
void GLCamera::SetCenterVec(double x, double y, double z) { // Set camera center vector. GLMatrix bt = fCamBase*fCamTrans; fCamBase.SetBaseVec(4, GLVector3(x, y, z)); GLMatrix binv = fCamBase; binv.Invert(); fCamTrans = binv*bt; }
bool ResizeWindow::glPaint (const GLWindowPaintAttrib &attrib, const GLMatrix &transform, const CompRegion ®ion, unsigned int mask) { bool status; if (window == static_cast<resize::CompWindowImpl*>(rScreen->logic.w)->impl () && rScreen->logic.mode == ResizeOptions::ModeStretch) { GLMatrix wTransform (transform); BoxRec box; float xOrigin, yOrigin; float xScale, yScale; int x, y; if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK) return false; status = gWindow->glPaint (attrib, transform, region, mask | PAINT_WINDOW_NO_CORE_INSTANCE_MASK); GLWindowPaintAttrib lastAttrib (gWindow->lastPaintAttrib ()); if (window->alpha () || lastAttrib.opacity != OPAQUE) mask |= PAINT_WINDOW_TRANSLUCENT_MASK; rScreen->logic.getPaintRectangle (&box); getStretchScale (&box, &xScale, &yScale); x = window->geometry (). x (); y = window->geometry (). y (); xOrigin = x - window->border ().left; yOrigin = y - window->border ().top; wTransform.translate (xOrigin, yOrigin, 0.0f); wTransform.scale (xScale, yScale, 1.0f); wTransform.translate ((rScreen->logic.geometry.x - x) / xScale - xOrigin, (rScreen->logic.geometry.y - y) / yScale - yOrigin, 0.0f); gWindow->glDraw (wTransform, lastAttrib, region, mask | PAINT_WINDOW_TRANSFORMED_MASK); } else { status = gWindow->glPaint (attrib, transform, region, mask); } return status; }
void MythRenderOpenGL2::PushTransformation(const UIEffects &fx, QPointF ¢er) { GLMatrix newtop = m_transforms.top(); if (fx.hzoom != 1.0 || fx.vzoom != 1.0 || fx.angle != 0.0) { newtop.translate(-center.x(), -center.y()); newtop.scale(fx.hzoom, fx.vzoom); newtop.rotate(fx.angle); newtop.translate(center.x(), center.y()); } m_transforms.push(newtop); }
void GLScreen::glEnableOutputClipping (const GLMatrix &transform, const CompRegion ®ion, CompOutput *output) { WRAPABLE_HND_FUNCTN (glEnableOutputClipping, transform, region, output) // Bottom-left corner of the output: const GLint x = output->x1 (); const GLint y = screen->height () - output->y2 (); const GLsizei w = output->width (); const GLsizei h = output->height (); // Transformed (only scale and translation is supported!) const float *t = transform.getMatrix (); const GLfloat scalex = t[0], scaley = t[5], transx = t[12], transy = t[13]; const GLfloat centrex = x + w / 2.0f; const GLfloat centrey = y + h / 2.0f; GLfloat scaledw = fabs (w * scalex); GLfloat scaledh = fabs (h * scaley); GLfloat tx = centrex - (scaledw / 2.0f) + transx * w; GLfloat ty = centrey - (scaledh / 2.0f) + transy * h; glScissor (tx, ty, roundf (scaledw), roundf (scaledh)); glEnable (GL_SCISSOR_TEST); }
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 CubeScreen::cubeCheckOrientation (const GLScreenPaintAttrib &sAttrib, const GLMatrix &transform, CompOutput *output, std::vector<GLVector> &points) { WRAPABLE_HND_FUNCTN_RETURN (bool, cubeCheckOrientation, sAttrib, transform, output, points) GLMatrix sTransform = transform; GLMatrix mvp, pm (priv->gScreen->projectionMatrix ()->getMatrix ()); GLVector pntA, pntB, pntC; GLVector vecA, vecB, ortho; bool rv = false; priv->gScreen->glApplyTransform (sAttrib, output, &sTransform); sTransform.translate (priv->mOutputXOffset, -priv->mOutputYOffset, 0.0f); sTransform.scale (priv->mOutputXScale, priv->mOutputYScale, 1.0f); mvp = pm * sTransform; pntA = mvp * points[0]; if (pntA[3] < 0.0f) rv = !rv; pntA.homogenize (); pntB = mvp * points[1]; if (pntB[3] < 0.0f) rv = !rv; pntB.homogenize (); pntC = mvp * points[2]; pntC.homogenize (); vecA = pntC - pntA; vecB = pntC - pntB; ortho = vecA ^ vecB; if (ortho[2] > 0.0f) rv = !rv; return rv; }
bool GLProgram::setUniform (const char *name, const GLMatrix &value) { GLint location = (*GL::getUniformLocation) (priv->program, name); if (location == -1) return false; (*GL::uniformMatrix4fv) (location, 1, GL_FALSE, value.getMatrix ()); return true; }
bool RotateScreen::glPaintOutput (const GLScreenPaintAttrib &sAttrib, const GLMatrix &transform, const CompRegion ®ion, CompOutput *output, unsigned int mask) { if (mGrabIndex || mMoving || mProgress != 0.0f) { GLMatrix sTransform = transform; sTransform.translate (0.0f, 0.0f, -mZoomTranslate); mask &= ~PAINT_SCREEN_REGION_MASK; mask |= PAINT_SCREEN_TRANSFORMED_MASK; return gScreen->glPaintOutput (sAttrib, sTransform, region, output, mask); } return gScreen->glPaintOutput (sAttrib, transform, region, output, mask); }
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 GLCamera::UpdateCache() { GLMatrix projm; glGetDoublev(GL_PROJECTION_MATRIX, projm.Arr()); GLMatrix modvm; glGetDoublev(GL_MODELVIEW_MATRIX, modvm.Arr()); GLMatrix clipm = projm; clipm *= modvm; fFrustumPlanes[kRight] .Set(clipm[ 3]-clipm[ 0], clipm[ 7]-clipm[ 4], clipm[11]-clipm[ 8], clipm[15]-clipm[12]); fFrustumPlanes[kLeft] .Set(clipm[ 3]+clipm[ 0], clipm[ 7]+clipm[ 4], clipm[11]+clipm[ 8], clipm[15]+clipm[12]); fFrustumPlanes[kBottom].Set(clipm[ 3]+clipm[ 1], clipm[ 7]+clipm[ 5], clipm[11]+clipm[ 9], clipm[15]+clipm[13]); fFrustumPlanes[kTop] .Set(clipm[ 3]-clipm[ 1], clipm[ 7]-clipm[ 5], clipm[11]-clipm[ 9], clipm[15]-clipm[13]); fFrustumPlanes[kFar] .Set(clipm[ 3]-clipm[ 2], clipm[ 7]-clipm[ 6], clipm[11]-clipm[10], clipm[15]-clipm[14]); fFrustumPlanes[kNear] .Set(clipm[ 3]+clipm[ 2], clipm[ 7]+clipm[ 6], clipm[11]+clipm[10], clipm[15]+clipm[14]); }
// transformIsSimple tells you if it's simple enough to use scissoring static bool transformIsSimple (const GLMatrix &transform) { const float *t = transform.getMatrix (); return // t[0] can be anything (x scale) t[1] == 0.0f && t[2] == 0.0f && t[3] == 0.0f && t[4] == 0.0f && // t[5] can be anything (y scale) t[6] == 0.0f && t[7] == 0.0f && t[8] == 0.0f && t[9] == 0.0f && // t[10] can be anything (z scale) t[11] == 0.0f && // t[12]..t[14] can be anything (translation) t[15] == 1.0f; }
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; }
void GLCamera::Apply(int pickx, int picky, int pickw, int pickh) { glViewport(vpX, vpY, vpW, vpH); if(vpW == 0 || vpH == 0) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); return; } glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(fieldOfView, vpW/vpH, 1.0, 1000.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); GLMatrix mx = fCamBase*fCamTrans; GLVector3 pos = mx.GetTranslation(); GLVector3 fwd = mx.GetBaseVec(1); GLVector3 center = pos-fwd; GLVector3 up = fCamBase.GetBaseVec(3); gluLookAt(pos[0], pos[1], pos[2], center[0], center[1], center[2], up[0], up[1], up[2]); UpdateCache(); GLPlane clipPlane(EyeDirection(), EyePoint()); for (int i = 0; i < 8; i++) { double sx = (i&1) ? -1 : 1; double sy = (i&2) ? -1 : 1; double sz = (i&4) ? -1 : 1; double cdist = clipPlane.DistanceTo(GLVertex3(sceneSize*sx, sceneSize*sy, sceneSize*sz)); if (i == 0) farClip = nearClip = cdist; if (cdist < nearClip) nearClip = cdist; if (cdist > farClip) farClip = cdist; } nearClip *= 0.49; farClip *= 2.01; if (farClip < 2.0) farClip = 2.0; if (nearClip < farClip/1000.0) nearClip = farClip/1000.0; glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (pickw > 0 && pickh > 0) { int vport[4] = { vpX, vpY, vpW, vpH }; gluPickMatrix(pickx, vpH-picky, pickw, pickh, vport); gluPerspective(fieldOfView, vpW/vpH, nearClip, farClip); } else gluPerspective(fieldOfView, vpW/vpH, nearClip, farClip); glMatrixMode(GL_MODELVIEW); UpdateCache(); }
void GearsScreen::cubePaintInside (const GLScreenPaintAttrib &sAttrib, const GLMatrix &transform, CompOutput *output, int size, const GLVector &normal) { // CUBE_SCREEN (screen); static GLfloat white[4] = { 1.0, 1.0, 1.0, 1.0 }; GLScreenPaintAttrib sA = sAttrib; sA.yRotate += csScreen->invert () * (360.0f / size) * (csScreen->xRotations () - (screen->vp ().x () * csScreen->nOutput ())); //CompTransform mT = *transform; GLMatrix mT = transform; gScreen->glApplyTransform (sA, output, &mT); // (*s->applyScreenTransform) (s, &sA, output, &mT); glPushMatrix(); glLoadMatrixf (mT.getMatrix ()); glTranslatef (csScreen->outputXOffset (), -csScreen->outputYOffset (), 0.0f); glScalef (csScreen->outputXScale (), csScreen->outputYScale (), 1.0f); bool enabledCull = false; glPushAttrib (GL_COLOR_BUFFER_BIT | GL_TEXTURE_BIT); glDisable (GL_BLEND); if (!glIsEnabled (GL_CULL_FACE) ) { enabledCull = true; glEnable (GL_CULL_FACE); } glPushMatrix(); glRotatef (contentRotation, 0.0, 1.0, 0.0); glScalef (0.05, 0.05, 0.05); glColor4usv (defaultColor); glEnable (GL_NORMALIZE); glEnable (GL_LIGHTING); glEnable (GL_LIGHT1); glDisable (GL_COLOR_MATERIAL); glEnable (GL_DEPTH_TEST); glDepthMask (GL_TRUE); glDepthFunc (GL_LESS); glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glPushMatrix(); glTranslatef (-3.0, -2.0, 0.0); glRotatef (angle, 0.0, 0.0, 1.0); glCallList (gear1); glPopMatrix(); glPushMatrix(); glTranslatef (3.1, -2.0, 0.0); glRotatef (-2.0 * angle - 9.0, 0.0, 0.0, 1.0); glCallList (gear2); glPopMatrix(); glPushMatrix(); glTranslatef (-3.1, 4.2, 0.0); glRotatef (-2.0 * angle - 25.0, 0.0, 0.0, 1.0); glCallList (gear3); glPopMatrix(); glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white); glPopMatrix(); glDisable (GL_LIGHT1); glDisable (GL_NORMALIZE); glEnable (GL_COLOR_MATERIAL); if (!gScreen->lighting ()) glDisable (GL_LIGHTING); glDisable (GL_DEPTH_TEST); if (enabledCull) glDisable (GL_CULL_FACE); glPopMatrix(); glPopAttrib(); damage = true; csScreen->cubePaintInside (sAttrib, transform, output, size, normal); }
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 update_rotation(const GLVector<XYZ>& rotation) { #ifndef M_PI #define M_PI 3.14159265359 #endif static const double to_rad = 1.0 / 180.0 * M_PI; GLMatrix mx; mx.set_data(0, 0, 1); mx.set_data(1, 1, cos(rotation[0] * to_rad)); mx.set_data(1, 2, sin(rotation[0] * to_rad)); mx.set_data(2, 2, mx.get_data(1, 1)); mx.set_data(2, 1, -mx.get_data(1, 2)); mx.set_data(3, 3, 1); GLMatrix my; my.set_data(0, 0, cos(rotation[1] * to_rad)); my.set_data(0, 2, -sin(rotation[1] * to_rad)); my.set_data(1, 1, 1); my.set_data(2, 0, -my.get_data(0, 2)); my.set_data(2, 2, my.get_data(0, 0)); my.set_data(3, 3, 1); GLMatrix mz; mz.set_data(0, 0, cos(rotation[2] * to_rad)); mz.set_data(0, 1, sin(rotation[2] * to_rad)); mz.set_data(1, 0, -mz.get_data(0, 1)); mz.set_data(1, 1, mz.get_data(0, 0)); mz.set_data(2, 2, 1); mz.set_data(3, 3, 1); update_rotation(mz * my * mx); }
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); }
/* This function currently always performs occlusion detection to minimize paint regions. OpenGL precision requirements are no good enough to guarantee that the results from using occlusion detection is the same as without. It's likely not possible to see any difference with most hardware but occlusion detection in the transformed screen case should be made optional for those who do see a difference. */ void PrivateGLScreen::paintOutputRegion (const GLMatrix &transform, const CompRegion ®ion, CompOutput *output, unsigned int mask) { CompRegion tmpRegion (region); CompWindow *w; GLWindow *gw; int windowMask, odMask; bool status, unredirectFS; bool withOffset = false; GLMatrix vTransform; CompPoint offXY; std::set<CompWindow*> unredirected; CompWindowList pl; CompWindowList::reverse_iterator rit; unredirectFS = CompositeScreen::get (screen)-> getOption ("unredirect_fullscreen_windows")->value ().b (); const CompMatch &unredirectable = CompositeScreen::get (screen)-> getOption ("unredirect_match")->value ().match (); const CompString &blacklist = getOption ("unredirect_driver_blacklist")->value ().s (); bool blacklisted = driverIsBlacklisted (blacklist.c_str ()); if (mask & PAINT_SCREEN_TRANSFORMED_MASK) { windowMask = PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK; } else { windowMask = 0; } /* * We need to COPY the PaintList for now because there seem to be some * odd cases where the master list might change during the below loops. * (LP: #958540) */ pl = cScreen->getWindowPaintList (); if (!(mask & PAINT_SCREEN_NO_OCCLUSION_DETECTION_MASK)) { FullscreenRegion fs (*output, screen->region ()); /* detect occlusions */ for (rit = pl.rbegin (); rit != pl.rend (); ++rit) { w = (*rit); gw = GLWindow::get (w); if (w->destroyed ()) continue; if (!w->shaded ()) { /* Non-damaged windows don't have valid pixmap * contents and we aren't displaying them yet * so don't factor them into occlusion detection */ if (!gw->priv->cWindow->damaged ()) { gw->priv->clip = region; continue; } if (!w->isViewable ()) continue; } /* copy region */ gw->priv->clip = tmpRegion; odMask = PAINT_WINDOW_OCCLUSION_DETECTION_MASK; if ((cScreen->windowPaintOffset ().x () != 0 || cScreen->windowPaintOffset ().y () != 0) && !w->onAllViewports ()) { withOffset = true; offXY = w->getMovementForOffset (cScreen->windowPaintOffset ()); vTransform = transform; vTransform.translate (offXY.x (), offXY.y (), 0); gw->priv->clip.translate (-offXY.x (), -offXY. y ()); odMask |= PAINT_WINDOW_WITH_OFFSET_MASK; status = gw->glPaint (gw->paintAttrib (), vTransform, tmpRegion, odMask); } else { withOffset = false; status = gw->glPaint (gw->paintAttrib (), transform, tmpRegion, odMask); } if (status) { if (withOffset) { tmpRegion -= w->region ().translated (offXY); } else tmpRegion -= w->region (); } FullscreenRegion::WinFlags flags = 0; if (w->type () & CompWindowTypeDesktopMask) flags |= FullscreenRegion::Desktop; if (w->alpha ()) flags |= FullscreenRegion::Alpha; /* Anything which was not occlusion detected is not a suitable * candidate for unredirection either */ if (!status) flags |= FullscreenRegion::NoOcclusionDetection; CompositeWindow *cw = CompositeWindow::get (w); /* * Windows with alpha channels can partially occlude windows * beneath them and so neither should be unredirected in that case. * * Performance note: unredirectable.evaluate is SLOW because it * involves regex matching. Too slow to do on every window for * every frame. So we only call it if a window is redirected AND * potentially needs unredirecting. This means changes to * unredirect_match while a window is unredirected already may not * take effect until it is un-fullscreened again. But that's better * than the high price of regex matching on every frame. */ if (unredirectFS && !blacklisted && !(mask & PAINT_SCREEN_TRANSFORMED_MASK) && !(mask & PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK) && fs.isCoveredBy (w->region (), flags) && (!cw->redirected () || unredirectable.evaluate (w))) { unredirected.insert (w); } else { if (!cw->redirected ()) { if (fs.allowRedirection (w->region ())) { // 1. GLWindow::release to force gw->priv->needsRebind gw->release (); // 2. GLWindow::bind, which redirects the window, // rebinds the pixmap, and then rebinds the pixmap // to a texture. gw->bind (); // 3. Your window is now redirected again with the // latest pixmap contents. } else { unredirected.insert (w); } } } } } /* Unredirect any redirected fullscreen windows */ foreach (CompWindow *fullscreenWindow, unredirected) CompositeWindow::get (fullscreenWindow)->unredirect (); if (!(mask & PAINT_SCREEN_NO_BACKGROUND_MASK)) paintBackground (transform, tmpRegion, (mask & PAINT_SCREEN_TRANSFORMED_MASK)); /* paint all windows from bottom to top */ foreach (w, pl) { if (w->destroyed ()) continue; gw = GLWindow::get (w); /* Release any queued ConfigureWindow requests now */ gw->priv->configureLock->release (); if (unredirected.find (w) != unredirected.end ()) continue; if (!w->shaded ()) { if (!w->isViewable ()) continue; } const CompRegion &clip = (!(mask & PAINT_SCREEN_NO_OCCLUSION_DETECTION_MASK)) ? gw->clip () : region; if ((cScreen->windowPaintOffset ().x () != 0 || cScreen->windowPaintOffset ().y () != 0) && !w->onAllViewports ()) { offXY = w->getMovementForOffset (cScreen->windowPaintOffset ()); vTransform = transform; vTransform.translate (offXY.x (), offXY.y (), 0); gw->glPaint (gw->paintAttrib (), vTransform, clip, windowMask | PAINT_WINDOW_WITH_OFFSET_MASK); } else { gw->glPaint (gw->paintAttrib (), transform, clip, windowMask); } } }