Beispiel #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 ();
}
Beispiel #2
0
void ShowFpsEffect::paintGraph(int x, int y, QList<int> values, QList<int> lines, bool colorize)
{
    if (effects->isOpenGLCompositing()) {
        QColor color(0, 0, 0);
        color.setAlphaF(alpha);
        GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer();
        vbo->reset();
        vbo->setColor(color);
        QVector<float> verts;
        // First draw the lines
        foreach (int h, lines) {
            verts << x << y - h;
            verts << x + values.count() << y - h;
        }
// Create buffers required for drawing the mesh on hardware. This must be called
// before rendering whenever the mesh has changed.
//
// return true if all hardware buffers could be created.
bool
MeshGeometry::realize() const
{
    // Mark hardware buffers as up-to-date. Even if vertex buffer allocation fails,
    // we don't want to keep retrying every time a frame is rendered.
    m_hwBuffersCurrent = true;

    // Only create vertex buffers for submeshes for which the size of the vertex
    // data exceeds the limit below.
    const unsigned int VertexBufferSizeThreshold = 4096;

    // Don't create anything if hardware/driver doesn't support vertex buffer objects,
    // but report success anyhow.
    if (!GLVertexBuffer::supported())
    {
        return true;
    }

    bool ok = true;
    freeSubmeshBuffers();

    for (vector< counted_ptr<Submesh> >::const_iterator iter = m_submeshes.begin();
         iter != m_submeshes.end(); ++iter)
    {
        Submesh* submesh = iter->ptr();
        GLVertexBuffer* vertexBuffer = NULL;

        unsigned int size = submesh->vertices()->stride() * submesh->vertices()->count();
        if (size > VertexBufferSizeThreshold)
        {
            vertexBuffer = new GLVertexBuffer(size, GL_STATIC_DRAW_ARB, submesh->vertices()->data());
            if (!vertexBuffer->isValid())
            {
                delete vertexBuffer;
                ok = false;
            }
        }

        // A null vertex pointer is legal and indicates that the vertex data is
        // stored in system memory instead of graphics memory.
        m_submeshBuffers.push_back(vertexBuffer);
    }

    return ok;
}
Beispiel #4
0
    void GLVertexBuffer::copyBuffer(const GraphicBufferPtr& to) {
        if(to) {
            GLVertexBuffer* dest = checked_cast<GLVertexBuffer*>(to.get());
            if(glCopyBufferSubData) {
                glBindBuffer(GL_COPY_READ_BUFFER, this->getGLBuffer());
                glBindBuffer(GL_COPY_WRITE_BUFFER, dest->getGLBuffer());

                CHECK_GL_CALL(glCopyBufferSubData(GL_COPY_READ_BUFFER,
                                    GL_COPY_WRITE_BUFFER,
                                    0,
                                    0,
                                    this->count() * GetVertexElementsTotalSize(this->format())));

                glBindBuffer(GL_COPY_READ_BUFFER, 0);
                glBindBuffer(GL_COPY_WRITE_BUFFER, 0);
            } else {
                log_error(L"GLVertexBuffer::copyBuffer: GL Copy Buffer Sub Data not supported");
            }
        }
    }
Beispiel #5
0
void MouseMarkEffect::paintScreen(int mask, QRegion region, ScreenPaintData& data)
{
    effects->paintScreen(mask, region, data);   // paint normal screen
    if (marks.isEmpty() && drawing.isEmpty())
        return;
    if ( effects->compositingType() == OpenGLCompositing) {
#ifndef KWIN_HAVE_OPENGLES
        glEnable(GL_LINE_SMOOTH);
#endif
        glLineWidth(width);
        GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer();
        vbo->reset();
        vbo->setUseColor(true);
        vbo->setColor(color);
        if (ShaderManager::instance()->isValid()) {
            ShaderManager::instance()->pushShader(ShaderManager::ColorShader);
        }
        QVector<float> verts;
        foreach (const Mark & mark, marks) {
            verts.clear();
            verts.reserve(mark.size() * 2);
            foreach (const QPoint & p, mark) {
                verts << p.x() << p.y();
            }
            vbo->setData(verts.size() / 2, 2, verts.data(), NULL);
            vbo->render(GL_LINE_STRIP);
        }
Beispiel #6
0
void ShowPaintEffect::paintGL()
{
    GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer();
    vbo->reset();
    vbo->setUseColor(true);
    if (ShaderManager::instance()->isValid()) {
        ShaderManager::instance()->pushShader(ShaderManager::ColorShader);
    }
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    QColor color = colors[ color_index ];
    color.setAlphaF(0.2);
    vbo->setColor(color);
    QVector<float> verts;
    verts.reserve(painted.rects().count() * 12);
    foreach (const QRect & r, painted.rects()) {
        verts << r.x() + r.width() << r.y();
        verts << r.x() << r.y();
        verts << r.x() << r.y() + r.height();
        verts << r.x() << r.y() + r.height();
        verts << r.x() + r.width() << r.y() + r.height();
        verts << r.x() + r.width() << r.y();
    }
    vbo->setData(verts.count() / 2, 2, verts.data(), NULL);
    vbo->render(GL_TRIANGLES);
    if (ShaderManager::instance()->isValid()) {
        ShaderManager::instance()->popShader();
    }
    glDisable(GL_BLEND);
}
Beispiel #7
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;
}
Beispiel #8
0
/*
	GL interop test.
	Julia.
*/
TEST(GLInteropTest, Julia)
{
	try
	{
		const int width = 1280;
		const int height = 720;
		const int bufWidth = 1920;
		const int bufHeight = 1080;

		// ------------------------------------------------------------

		GLTestWindow window(width, height, true);
		GLContextParam param;

		param.DebugMode = true;
		param.Multisample = 8;

		GLContext context(window.Handle(), param);
		GLUtil::EnableDebugOutput(GLUtil::DebugOutputFrequencyLow);

		// ------------------------------------------------------------

		// Choose device
		cudaDeviceProp prop;
		memset(&prop, 0, sizeof(cudaDeviceProp));
		prop.major = 2;
		prop.minor = 0;

		int devID;
		HandleCudaError(cudaChooseDevice(&devID, &prop));
		HandleCudaError(cudaGLSetGLDevice(devID));

		// Get properties
		HandleCudaError(cudaGetDeviceProperties(&prop, devID));

		// Create texture and PBO
		GLTexture2D texture;
		texture.SetMagFilter(GL_LINEAR);
		texture.SetMinFilter(GL_LINEAR);
		texture.SetWrap(GL_CLAMP_TO_EDGE);
		texture.Allocate(bufWidth, bufHeight, GL_RGBA8);
		
		GLPixelUnpackBuffer pbo;
		pbo.Allocate(bufWidth * bufHeight * 4, NULL, GL_DYNAMIC_DRAW);

		// Register
		cudaGraphicsResource* cudaPbo;
		HandleCudaError(cudaGraphicsGLRegisterBuffer(&cudaPbo, pbo.ID(), cudaGraphicsMapFlagsWriteDiscard));

		// ------------------------------------------------------------

		GLShader shader;
		shader.Compile("../resources/texturetest_simple2d.vert");
		shader.Compile("../resources/texturetest_simple2d.frag");
		shader.Link();

		GLVertexArray vao;
		GLVertexBuffer positionVbo;
		GLIndexBuffer ibo;

		glm::vec3 v[] =
		{
			glm::vec3( 1.0f,  1.0f, 0.0f),
			glm::vec3(-1.0f,  1.0f, 0.0f),
			glm::vec3(-1.0f, -1.0f, 0.0f),
			glm::vec3( 1.0f, -1.0f, 0.0f)
		};

		GLuint i[] =
		{
			0, 1, 2,
			2, 3, 0
		};

		positionVbo.AddStatic(12, &v[0].x);
		vao.Add(GLDefaultVertexAttribute::Position, &positionVbo);
		ibo.AddStatic(6, i);

		// ------------------------------------------------------------

		double fps = 0.0;
		double timeSum = 0.0;
		double prevTime = GLTestUtil::CurrentTimeMilli();
		int frameCount = 0;

		double start = GLTestUtil::CurrentTimeMilli();
		float xcparam = -0.8f;
		float ycparam = 0.165f;
		float inc = 0.001f;

		while (window.ProcessEvent())
		{
			// ------------------------------------------------------------

			double currentTime = GLTestUtil::CurrentTimeMilli();
			double elapsedTime = currentTime - prevTime;

			timeSum += elapsedTime;
			frameCount++;

			if (frameCount >= 13)
			{
				fps = 1000.0 * 13.0 / timeSum;
				timeSum = 0.0;
				frameCount = 0;
			}

			prevTime = currentTime;
			window.SetTitle((boost::format("GLInteropTest_Julia [FPS %.1f]") % fps).str());

			// ------------------------------------------------------------

			double elapsed = GLTestUtil::CurrentTimeMilli() - start;
			if (elapsed >= 1000.0)
			{
				break;
			}

			xcparam += inc;
			if (xcparam > -0.799f || xcparam < -0.811f) 
			{
				inc *= -1.0f;
			}

			// ------------------------------------------------------------

			HandleCudaError(cudaGraphicsMapResources(1, &cudaPbo, NULL));
			
			// Get device pointer
			uchar4* devPtr;
			size_t bufferSize;
			HandleCudaError(cudaGraphicsResourceGetMappedPointer((void**)&devPtr, &bufferSize, cudaPbo));
			Run_GLInteropTestJuliaKernel(bufWidth, bufHeight, prop.multiProcessorCount, xcparam, ycparam, devPtr);
			HandleCudaError(cudaGraphicsUnmapResources(1, &cudaPbo, NULL));

			texture.Replace(&pbo, glm::ivec4(0, 0, bufWidth, bufHeight), GL_RGBA, GL_UNSIGNED_BYTE);

			// ------------------------------------------------------------

			glClearBufferfv(GL_COLOR, 0, glm::value_ptr(glm::vec4(0.0f)));
			glViewportIndexedfv(0, glm::value_ptr(glm::vec4(0, 0, width, height)));

			shader.Begin();
			shader.SetUniform("tex", 0);
			texture.Bind();
			vao.Draw(GL_TRIANGLES, &ibo);
			texture.Unbind();
			shader.End();

			context.SwapBuffers();
		}

		cudaDeviceReset();
	}
	catch (const GLException& e)
	{
		FAIL() << GLTestUtil::PrintGLException(e);
	}
}
Beispiel #9
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;

	    }
	}
    }
}
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;
}
Beispiel #11
0
void CoverSwitchEffect::paintScreen(int mask, QRegion region, ScreenPaintData& data)
{
    effects->paintScreen(mask, region, data);

    if (mActivated || stop || stopRequested) {

        QList< EffectWindow* > tempList = currentWindowList;
        int index = tempList.indexOf(selected_window);
        if (animation || start || stop) {
            if (!start && !stop) {
                if (direction == Right)
                    index++;
                else
                    index--;
                if (index < 0)
                    index = tempList.count() + index;
                if (index >= tempList.count())
                    index = index % tempList.count();
            }
            foreach (Direction direction, scheduled_directions) {
                if (direction == Right)
                    index++;
                else
                    index--;
                if (index < 0)
                    index = tempList.count() + index;
                if (index >= tempList.count())
                    index = index % tempList.count();
            }
        }
        int leftIndex = index - 1;
        if (leftIndex < 0)
            leftIndex = tempList.count() - 1;
        int rightIndex = index + 1;
        if (rightIndex == tempList.count())
            rightIndex = 0;

        EffectWindow* frontWindow = tempList[ index ];
        leftWindows.clear();
        rightWindows.clear();

        bool evenWindows = (tempList.count() % 2 == 0) ? true : false;
        int leftWindowCount = 0;
        if (evenWindows)
            leftWindowCount = tempList.count() / 2 - 1;
        else
            leftWindowCount = (tempList.count() - 1) / 2;
        for (int i = 0; i < leftWindowCount; i++) {
            int tempIndex = (leftIndex - i);
            if (tempIndex < 0)
                tempIndex = tempList.count() + tempIndex;
            leftWindows.prepend(tempList[ tempIndex ]);
        }
        int rightWindowCount = 0;
        if (evenWindows)
            rightWindowCount = tempList.count() / 2;
        else
            rightWindowCount = (tempList.count() - 1) / 2;
        for (int i = 0; i < rightWindowCount; i++) {
            int tempIndex = (rightIndex + i) % tempList.count();
            rightWindows.prepend(tempList[ tempIndex ]);
        }

        if (reflection) {
            // no reflections during start and stop animation
            // except when using a shader
            if ((!start && !stop) || effects->compositingType() == OpenGL2Compositing)
                paintScene(frontWindow, leftWindows, rightWindows, true);
            glEnable(GL_BLEND);
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
            // we can use a huge scale factor (needed to calculate the rearground vertices)
            // as we restrict with a PaintClipper painting on the current screen
            float reflectionScaleFactor = 100000 * tan(60.0 * M_PI / 360.0f) / area.width();
            const float width = area.width();
            const float height = area.height();
            float vertices[] = {
                -width * 0.5f, height, 0.0,
                width * 0.5f, height, 0.0,
                width*reflectionScaleFactor, height, -5000,
                -width*reflectionScaleFactor, height, -5000
            };
            // foreground
            if (start) {
                mirrorColor[0][3] = timeLine.currentValue();
            } else if (stop) {
                mirrorColor[0][3] = 1.0 - timeLine.currentValue();
            } else {
                mirrorColor[0][3] = 1.0;
            }

            int y = 0;
            // have to adjust the y values to fit OpenGL
            // in OpenGL y==0 is at bottom, in Qt at top
            if (effects->numScreens() > 1) {
                QRect fullArea = effects->clientArea(FullArea, 0, 1);
                if (fullArea.height() != area.height()) {
                    if (area.y() == 0)
                        y = fullArea.height() - area.height();
                    else
                        y = fullArea.height() - area.y() - area.height();
                }
            }
            // use scissor to restrict painting of the reflection plane to current screen
            glScissor(area.x(), y, area.width(), area.height());
            glEnable(GL_SCISSOR_TEST);

            if (m_reflectionShader && m_reflectionShader->isValid()) {
                ShaderManager::instance()->pushShader(m_reflectionShader);
                QMatrix4x4 windowTransformation;
                windowTransformation.translate(area.x() + area.width() * 0.5f, 0.0, 0.0);
                m_reflectionShader->setUniform("windowTransformation", windowTransformation);
                m_reflectionShader->setUniform("u_frontColor", QVector4D(mirrorColor[0][0], mirrorColor[0][1], mirrorColor[0][2], mirrorColor[0][3]));
                m_reflectionShader->setUniform("u_backColor", QVector4D(mirrorColor[1][0], mirrorColor[1][1], mirrorColor[1][2], mirrorColor[1][3]));
                // TODO: make this one properly
                QVector<float> verts;
                QVector<float> texcoords;
                verts.reserve(18);
                texcoords.reserve(12);
                texcoords << 1.0 << 0.0;
                verts << vertices[6] << vertices[7] << vertices[8];
                texcoords << 1.0 << 0.0;
                verts << vertices[9] << vertices[10] << vertices[11];
                texcoords << 0.0 << 0.0;
                verts << vertices[0] << vertices[1] << vertices[2];
                texcoords << 0.0 << 0.0;
                verts << vertices[0] << vertices[1] << vertices[2];
                texcoords << 0.0 << 0.0;
                verts << vertices[3] << vertices[4] << vertices[5];
                texcoords << 1.0 << 0.0;
                verts << vertices[6] << vertices[7] << vertices[8];
                GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer();
                vbo->reset();
                vbo->setData(6, 3, verts.data(), texcoords.data());
                vbo->render(GL_TRIANGLES);

                ShaderManager::instance()->popShader();
            }
            glDisable(GL_SCISSOR_TEST);
            glDisable(GL_BLEND);
        }
        paintScene(frontWindow, leftWindows, rightWindows);

        // Render the caption frame
        if (windowTitle) {
            double opacity = 1.0;
            if (start)
                opacity = timeLine.currentValue();
            else if (stop)
                opacity = 1.0 - timeLine.currentValue();
            if (animation)
                captionFrame->setCrossFadeProgress(timeLine.currentValue());
            captionFrame->render(region, opacity);
        }
    }
Beispiel #12
0
void CoverSwitchEffect::paintScreen(int mask, QRegion region, ScreenPaintData& data)
{
    effects->paintScreen(mask, region, data);

    if (mActivated || stop || stopRequested) {
        QMatrix4x4 origProjection;
        QMatrix4x4 origModelview;
        ShaderManager *shaderManager = ShaderManager::instance();
        if (effects->numScreens() > 1) {
            // unfortunatelly we have to change the projection matrix in dual screen mode
            QRect fullRect = effects->clientArea(FullArea, activeScreen, effects->currentDesktop());
            float fovy = 60.0f;
            float aspect = 1.0f;
            float zNear = 0.1f;
            float zFar = 100.0f;
            float ymax = zNear * tan(fovy  * M_PI / 360.0f);
            float ymin = -ymax;
            float xmin =  ymin * aspect;
            float xmax = ymax * aspect;
            float xTranslate = 0.0;
            float yTranslate = 0.0;
            float xminFactor = 1.0;
            float xmaxFactor = 1.0;
            float yminFactor = 1.0;
            float ymaxFactor = 1.0;
            if (area.x() == 0 && area.width() != fullRect.width()) {
                // horizontal layout: left screen
                xminFactor = (float)area.width() / (float)fullRect.width();
                xmaxFactor = ((float)fullRect.width() - (float)area.width() * 0.5f) / ((float)fullRect.width() * 0.5f);
                xTranslate = (float)fullRect.width() * 0.5f - (float)area.width() * 0.5f;
            }
            if (area.x() != 0 && area.width() != fullRect.width()) {
                // horizontal layout: right screen
                xminFactor = ((float)fullRect.width() - (float)area.width() * 0.5f) / ((float)fullRect.width() * 0.5f);
                xmaxFactor = (float)area.width() / (float)fullRect.width();
                xTranslate = (float)fullRect.width() * 0.5f - (float)area.width() * 0.5f;
            }
            if (area.y() == 0 && area.height() != fullRect.height()) {
                // vertical layout: top screen
                yminFactor = ((float)fullRect.height() - (float)area.height() * 0.5f) / ((float)fullRect.height() * 0.5f);
                ymaxFactor = (float)area.height() / (float)fullRect.height();
                yTranslate = (float)fullRect.height() * 0.5f - (float)area.height() * 0.5f;
            }
            if (area.y() != 0 && area.height() != fullRect.height()) {
                // vertical layout: bottom screen
                yminFactor = (float)area.height() / (float)fullRect.height();
                ymaxFactor = ((float)fullRect.height() - (float)area.height() * 0.5f) / ((float)fullRect.height() * 0.5f);
                yTranslate = (float)fullRect.height() * 0.5f - (float)area.height() * 0.5f;
            }
            QMatrix4x4 projection;
            projection.frustum(xmin * xminFactor, xmax * xmaxFactor, ymin * yminFactor, ymax * ymaxFactor, zNear, zFar);
            QMatrix4x4 modelview;
            modelview.translate(xTranslate, yTranslate, 0.0);
            if (shaderManager->isShaderBound()) {
                GLShader *shader = shaderManager->pushShader(ShaderManager::GenericShader);
                origProjection = shader->getUniformMatrix4x4("projection");
                origModelview = shader->getUniformMatrix4x4("modelview");
                shader->setUniform("projection", projection);
                shader->setUniform("modelview", origModelview * modelview);
                shaderManager->popShader();
            } else {
#ifndef KWIN_HAVE_OPENGLES
                glMatrixMode(GL_PROJECTION);
                pushMatrix();
                loadMatrix(projection);
                glMatrixMode(GL_MODELVIEW);
                pushMatrix(modelview);
#endif
            }
        }

        QList< EffectWindow* > tempList = currentWindowList;
        int index = tempList.indexOf(selected_window);
        if (animation || start || stop) {
            if (!start && !stop) {
                if (direction == Right)
                    index++;
                else
                    index--;
                if (index < 0)
                    index = tempList.count() + index;
                if (index >= tempList.count())
                    index = index % tempList.count();
            }
            foreach (Direction direction, scheduled_directions) {
                if (direction == Right)
                    index++;
                else
                    index--;
                if (index < 0)
                    index = tempList.count() + index;
                if (index >= tempList.count())
                    index = index % tempList.count();
            }
        }
        int leftIndex = index - 1;
        if (leftIndex < 0)
            leftIndex = tempList.count() - 1;
        int rightIndex = index + 1;
        if (rightIndex == tempList.count())
            rightIndex = 0;

        EffectWindow* frontWindow = tempList[ index ];
        leftWindows.clear();
        rightWindows.clear();

        bool evenWindows = (tempList.count() % 2 == 0) ? true : false;
        int leftWindowCount = 0;
        if (evenWindows)
            leftWindowCount = tempList.count() / 2 - 1;
        else
            leftWindowCount = (tempList.count() - 1) / 2;
        for (int i = 0; i < leftWindowCount; i++) {
            int tempIndex = (leftIndex - i);
            if (tempIndex < 0)
                tempIndex = tempList.count() + tempIndex;
            leftWindows.prepend(tempList[ tempIndex ]);
        }
        int rightWindowCount = 0;
        if (evenWindows)
            rightWindowCount = tempList.count() / 2;
        else
            rightWindowCount = (tempList.count() - 1) / 2;
        for (int i = 0; i < rightWindowCount; i++) {
            int tempIndex = (rightIndex + i) % tempList.count();
            rightWindows.prepend(tempList[ tempIndex ]);
        }

        if (reflection) {
            // no reflections during start and stop animation
            // except when using a shader
            if ((!start && !stop) || ShaderManager::instance()->isValid())
                paintScene(frontWindow, leftWindows, rightWindows, true);
            glEnable(GL_BLEND);
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
#ifndef KWIN_HAVE_OPENGLES
            glPolygonMode(GL_FRONT, GL_FILL);
#endif
            QRect fullRect = effects->clientArea(FullArea, activeScreen, effects->currentDesktop());
            // we can use a huge scale factor (needed to calculate the rearground vertices)
            // as we restrict with a PaintClipper painting on the current screen
            float reflectionScaleFactor = 100000 * tan(60.0 * M_PI / 360.0f) / area.width();
            float vertices[] = {
                -area.width() * 0.5f, area.height(), 0.0,
                area.width() * 0.5f, area.height(), 0.0,
                (float)area.width()*reflectionScaleFactor, area.height(), -5000,
                -(float)area.width()*reflectionScaleFactor, area.height(), -5000
            };
            // foreground
            if (start) {
                mirrorColor[0][3] = timeLine.currentValue();
            } else if (stop) {
                mirrorColor[0][3] = 1.0 - timeLine.currentValue();
            } else {
                mirrorColor[0][3] = 1.0;
            }

            int y = 0;
            // have to adjust the y values to fit OpenGL
            // in OpenGL y==0 is at bottom, in Qt at top
            if (effects->numScreens() > 1) {
                QRect fullArea = effects->clientArea(FullArea, 0, 1);
                if (fullArea.height() != area.height()) {
                    if (area.y() == 0)
                        y = fullArea.height() - area.height();
                    else
                        y = fullArea.height() - area.y() - area.height();
                }
            }
            // use scissor to restrict painting of the reflection plane to current screen
            glScissor(area.x(), y, area.width(), area.height());
            glEnable(GL_SCISSOR_TEST);

            if (shaderManager->isValid() && m_reflectionShader->isValid()) {
                shaderManager->pushShader(m_reflectionShader);
                QMatrix4x4 windowTransformation;
                windowTransformation.translate(area.x() + area.width() * 0.5f, 0.0, 0.0);
                m_reflectionShader->setUniform("windowTransformation", windowTransformation);
                m_reflectionShader->setUniform("u_frontColor", QVector4D(mirrorColor[0][0], mirrorColor[0][1], mirrorColor[0][2], mirrorColor[0][3]));
                m_reflectionShader->setUniform("u_backColor", QVector4D(mirrorColor[1][0], mirrorColor[1][1], mirrorColor[1][2], mirrorColor[1][3]));
                // TODO: make this one properly
                QVector<float> verts;
                QVector<float> texcoords;
                verts.reserve(18);
                texcoords.reserve(12);
                texcoords << 1.0 << 0.0;
                verts << vertices[6] << vertices[7] << vertices[8];
                texcoords << 1.0 << 0.0;
                verts << vertices[9] << vertices[10] << vertices[11];
                texcoords << 0.0 << 0.0;
                verts << vertices[0] << vertices[1] << vertices[2];
                texcoords << 0.0 << 0.0;
                verts << vertices[0] << vertices[1] << vertices[2];
                texcoords << 0.0 << 0.0;
                verts << vertices[3] << vertices[4] << vertices[5];
                texcoords << 1.0 << 0.0;
                verts << vertices[6] << vertices[7] << vertices[8];
                GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer();
                vbo->reset();
                vbo->setData(6, 3, verts.data(), texcoords.data());
                vbo->render(GL_TRIANGLES);

                shaderManager->popShader();
            } else {
#ifndef KWIN_HAVE_OPENGLES
                glPushMatrix();
                if (effects->numScreens() > 1 && area.x() != fullRect.x()) {
                    // have to change the reflection area in horizontal layout and right screen
                    glTranslatef(-area.x(), 0.0, 0.0);
                }
                glTranslatef(area.x() + area.width() * 0.5f, 0.0, 0.0);
                glColor4fv(mirrorColor[0]);
                glBegin(GL_POLYGON);
                glVertex3f(vertices[0], vertices[1], vertices[2]);
                glVertex3f(vertices[3], vertices[4], vertices[5]);
                // rearground
                glColor4fv(mirrorColor[1]);
                glVertex3f(vertices[6], vertices[7], vertices[8]);
                glVertex3f(vertices[9], vertices[10], vertices[11]);
                glEnd();

                glPopMatrix();
#endif
            }
            glDisable(GL_SCISSOR_TEST);
            glDisable(GL_BLEND);
        }
        paintScene(frontWindow, leftWindows, rightWindows);

        if (effects->numScreens() > 1) {
            if (shaderManager->isShaderBound())  {
                GLShader *shader = shaderManager->pushShader(ShaderManager::GenericShader);
                shader->setUniform("projection", origProjection);
                shader->setUniform("modelview", origModelview);
                shaderManager->popShader();
            } else {
#ifndef KWIN_HAVE_OPENGLES
                popMatrix();
                // revert change of projection matrix
                glMatrixMode(GL_PROJECTION);
                popMatrix();
                glMatrixMode(GL_MODELVIEW);
#endif
            }
        }

        // Render the caption frame
        if (windowTitle) {
            double opacity = 1.0;
            if (start)
                opacity = timeLine.currentValue();
            else if (stop)
                opacity = 1.0 - timeLine.currentValue();
            if (animation)
                captionFrame->setCrossFadeProgress(timeLine.currentValue());
            captionFrame->render(region, opacity);
        }

        if ((thumbnails && (!dynamicThumbnails ||
                           (dynamicThumbnails && currentWindowList.size() >= thumbnailWindows)))
                && !(start || stop)) {
            BoxSwitchEffectProxy *proxy =
                static_cast<BoxSwitchEffectProxy*>(effects->getProxy("boxswitch"));
            if (proxy)
                proxy->paintWindowsBox(region);
        }
    }
Beispiel #13
0
	void GLDevice::RDUnlockBuffer(RDVertexBufferP iBuffer)
	{
		GLVertexBuffer * buffer = static_cast<GLVertexBuffer *>(iBuffer);
		buffer->Unlock(GetCurrentContext());
	}
Beispiel #14
0
void ShowFpsEffect::paintGL(int fps)
{
    int x = this->x;
    int y = this->y;
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    // TODO painting first the background white and then the contents
    // means that the contents also blend with the background, I guess
    ShaderBinder binder(ShaderManager::ColorShader);
    GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer();
    vbo->reset();
    QColor color(255, 255, 255);
    color.setAlphaF(alpha);
    vbo->setColor(color);
    QVector<float> verts;
    verts.reserve(12);
    verts << x + 2 * NUM_PAINTS + FPS_WIDTH << y;
    verts << x << y;
    verts << x << y + MAX_TIME;
    verts << x << y + MAX_TIME;
    verts << x + 2 * NUM_PAINTS + FPS_WIDTH << y + MAX_TIME;
    verts << x + 2 * NUM_PAINTS + FPS_WIDTH << y;
    vbo->setData(6, 2, verts.constData(), NULL);
    vbo->render(GL_TRIANGLES);
    y += MAX_TIME; // paint up from the bottom
    color.setRed(0);
    color.setGreen(0);
    vbo->setColor(color);
    verts.clear();
    verts << x + FPS_WIDTH << y - fps;
    verts << x << y - fps;
    verts << x << y;
    verts << x << y;
    verts << x + FPS_WIDTH << y;
    verts << x + FPS_WIDTH << y - fps;
    vbo->setData(6, 2, verts.constData(), NULL);
    vbo->render(GL_TRIANGLES);


    color.setBlue(0);
    vbo->setColor(color);
    QVector<float> vertices;
    for (int i = 10;
            i < MAX_TIME;
            i += 10) {
        vertices << x << y - i;
        vertices << x + FPS_WIDTH << y - i;
    }
    vbo->setData(vertices.size() / 2, 2, vertices.constData(), NULL);
    vbo->render(GL_LINES);
    x += FPS_WIDTH;

    // Paint FPS graph
    paintFPSGraph(x, y);
    x += NUM_PAINTS;

    // Paint amount of rendered pixels graph
    paintDrawSizeGraph(x, y);

    // Paint FPS numerical value
    if (fpsTextRect.isValid()) {
        fpsText.reset(new GLTexture(fpsTextImage(fps)));
        fpsText->bind();
        ShaderBinder binder(ShaderManager::SimpleShader);
        if (effects->compositingType() == OpenGL2Compositing) {
            binder.shader()->setUniform("offset", QVector2D(0, 0));
        }
        fpsText->render(QRegion(fpsTextRect), fpsTextRect);
        fpsText->unbind();
        effects->addRepaint(fpsTextRect);
    }

    // Paint paint sizes
    glDisable(GL_BLEND);
}
Beispiel #15
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 ();
}
Beispiel #16
0
void SnapHelperEffect::postPaintScreen()
{
    effects->postPaintScreen();
    if (m_timeline.currentValue() != 0.0) {
        // Display the guide
        if (effects->isOpenGLCompositing()) {
            GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer();
            vbo->reset();
            vbo->setUseColor(true);
            ShaderBinder binder(ShaderManager::ColorShader);
            glEnable(GL_BLEND);
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

            QColor color;
            color.setRedF(0.5);
            color.setGreenF(0.5);
            color.setBlueF(0.5);
            color.setAlphaF(m_timeline.currentValue() * 0.5);
            vbo->setColor(color);
            glLineWidth(4.0);
            QVector<float> verts;
            verts.reserve(effects->numScreens() * 24);
            for (int i = 0; i < effects->numScreens(); ++i) {
                const QRect& rect = effects->clientArea(ScreenArea, i, 0);
                int midX = rect.x() + rect.width() / 2;
                int midY = rect.y() + rect.height() / 2 ;
                int halfWidth = m_window->width() / 2;
                int halfHeight = m_window->height() / 2;

                // Center lines
                verts << rect.x() + rect.width() / 2 << rect.y();
                verts << rect.x() + rect.width() / 2 << rect.y() + rect.height();
                verts << rect.x() << rect.y() + rect.height() / 2;
                verts << rect.x() + rect.width() << rect.y() + rect.height() / 2;

                // Window outline
                // The +/- 2 is to prevent line overlap
                verts << midX - halfWidth + 2 << midY - halfHeight;
                verts << midX + halfWidth + 2 << midY - halfHeight;
                verts << midX + halfWidth << midY - halfHeight + 2;
                verts << midX + halfWidth << midY + halfHeight + 2;
                verts << midX + halfWidth - 2 << midY + halfHeight;
                verts << midX - halfWidth - 2 << midY + halfHeight;
                verts << midX - halfWidth << midY + halfHeight - 2;
                verts << midX - halfWidth << midY - halfHeight - 2;
            }
            vbo->setData(verts.count() / 2, 2, verts.data(), NULL);
            vbo->render(GL_LINES);

            glDisable(GL_BLEND);
            glLineWidth(1.0);
        }
        if ( effects->compositingType() == XRenderCompositing ) {
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
            for (int i = 0; i < effects->numScreens(); ++i) {
                const QRect& rect = effects->clientArea( ScreenArea, i, 0 );
                int midX = rect.x() + rect.width() / 2;
                int midY = rect.y() + rect.height() / 2 ;
                int halfWidth = m_window->width() / 2;
                int halfHeight = m_window->height() / 2;

                xcb_rectangle_t rects[6];
                // Center lines
                rects[0].x = rect.x() + rect.width() / 2 - 2;
                rects[0].y = rect.y();
                rects[0].width = 4;
                rects[0].height = rect.height();
                rects[1].x = rect.x();
                rects[1].y = rect.y() + rect.height() / 2 - 2;
                rects[1].width = rect.width();
                rects[1].height = 4;

                // Window outline
                // The +/- 4 is to prevent line overlap
                rects[2].x = midX - halfWidth + 4;
                rects[2].y = midY - halfHeight;
                rects[2].width = 2*halfWidth - 4;
                rects[2].height = 4;
                rects[3].x = midX + halfWidth - 4;
                rects[3].y = midY - halfHeight + 4;
                rects[3].width = 4;
                rects[3].height = 2*halfHeight - 4;
                rects[4].x = midX - halfWidth;
                rects[4].y = midY + halfHeight - 4;
                rects[4].width = 2*halfWidth - 4;
                rects[4].height = 4;
                rects[5].x = midX - halfWidth;
                rects[5].y = midY - halfHeight;
                rects[5].width = 4;
                rects[5].height = 2*halfHeight - 4;

                xcb_render_fill_rectangles(xcbConnection(), XCB_RENDER_PICT_OP_OVER, effects->xrenderBufferPicture(),
                                           preMultiply(QColor(128, 128, 128, m_timeline.currentValue()*128)), 6, rects);
            }
#endif
        }
        if (effects->compositingType() == QPainterCompositing) {
            QPainter *painter = effects->scenePainter();
            painter->save();
            QColor color;
            color.setRedF(0.5);
            color.setGreenF(0.5);
            color.setBlueF(0.5);
            color.setAlphaF(m_timeline.currentValue() * 0.5);
            QPen pen(color);
            pen.setWidth(4);
            painter->setPen(pen);
            painter->setBrush(Qt::NoBrush);

            for (int i = 0; i < effects->numScreens(); ++i) {
                const QRect &rect = effects->clientArea(ScreenArea, i, 0);
                // Center lines
                painter->drawLine(rect.center().x(), rect.y(), rect.center().x(), rect.y() + rect.height());
                painter->drawLine(rect.x(), rect.center().y(), rect.x() + rect.width(), rect.center().y());

                // window outline
                QRect windowRect(rect.center(), m_window->geometry().size());
                painter->drawRect(windowRect.translated(-windowRect.width()/2, -windowRect.height()/2));
            }
            painter->restore();
        }
    } else if (m_window && !m_active) {
        if (m_window->isDeleted())
            m_window->unrefWindow();
        m_window = NULL;
    }
}
Beispiel #17
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
}
Beispiel #18
0
void ResizeEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
{
    if (m_active && w == m_resizeWindow) {
        if (m_features & TextureScale) {
            data.xTranslate += m_currentGeometry.x() - m_originalGeometry.x();
            data.xScale *= m_currentGeometry.width();
            data.xScale /= m_originalGeometry.width();
            data.yTranslate += m_currentGeometry.y() - m_originalGeometry.y();
            data.yScale *= m_currentGeometry.height();
            data.yScale /= m_originalGeometry.height();
        }
        effects->paintWindow(w, mask, region, data);

        if (m_features & Outline) {
            QRegion intersection = m_originalGeometry.intersected(m_currentGeometry);
            QRegion paintRegion = QRegion(m_originalGeometry).united(m_currentGeometry).subtracted(intersection);
            float alpha = 0.8f;
            QColor color = KColorScheme(QPalette::Normal, KColorScheme::Selection).background().color();

#ifdef KWIN_HAVE_OPENGL
            if (effects->compositingType() == OpenGLCompositing) {
                GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer();
                vbo->reset();
                vbo->setUseColor(true);
                if (ShaderManager::instance()->isValid()) {
                    ShaderManager::instance()->pushShader(ShaderManager::ColorShader);
                }
                glEnable(GL_BLEND);
                glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
                color.setAlphaF(alpha);
                vbo->setColor(color);
                QVector<float> verts;
                verts.reserve(paintRegion.rects().count() * 12);
                foreach (const QRect & r, paintRegion.rects()) {
                    verts << r.x() + r.width() << r.y();
                    verts << r.x() << r.y();
                    verts << r.x() << r.y() + r.height();
                    verts << r.x() << r.y() + r.height();
                    verts << r.x() + r.width() << r.y() + r.height();
                    verts << r.x() + r.width() << r.y();
                }
                vbo->setData(verts.count() / 2, 2, verts.data(), NULL);
                vbo->render(GL_TRIANGLES);
                if (ShaderManager::instance()->isValid()) {
                    ShaderManager::instance()->popShader();
                }
                glDisable(GL_BLEND);
            }
#endif

#ifdef KWIN_HAVE_XRENDER_COMPOSITING
            if (effects->compositingType() == XRenderCompositing) {
                XRenderColor col;
                col.alpha = int(alpha * 0xffff);
                col.red = int(alpha * 0xffff * color.red() / 255);
                col.green = int(alpha * 0xffff * color.green() / 255);
                col.blue = int(alpha * 0xffff * color.blue() / 255);
                foreach (const QRect & r, paintRegion.rects())
                XRenderFillRectangle(display(), PictOpOver, effects->xrenderBufferPicture(),
                                     &col, r.x(), r.y(), r.width(), r.height());
            }
void
MeshGeometry::renderShadow(RenderContext& rc,
                           double /* clock */) const
{
    if (!m_hwBuffersCurrent)
    {
        realize();
    }

    // Use an extremely basic material to avoid wasting time
    // with pixel shader calculations when we're just interested
    // in depth values.
    Material simpleMaterial;
    rc.bindMaterial(&simpleMaterial);

    rc.pushModelView();
    rc.scaleModelView(m_meshScale);

    // Render all submeshes
    GLVertexBuffer* boundVertexBuffer = NULL;
    for (unsigned int i = 0; i < m_submeshes.size(); ++i)
    {
        const Submesh& submesh = *m_submeshes[i];

        if (i < m_submeshBuffers.size() && m_submeshBuffers[i])
        {
            boundVertexBuffer = m_submeshBuffers[i];
            rc.bindVertexBuffer(submesh.vertices()->vertexSpec(), m_submeshBuffers[i], submesh.vertices()->stride());
        }
        else
        {
            if (boundVertexBuffer)
            {
                boundVertexBuffer->unbind();
                boundVertexBuffer = false;
            }
            rc.bindVertexArray(submesh.vertices());
        }

        const vector<PrimitiveBatch*>& batches = submesh.primitiveBatches();
        const vector<unsigned int>& materials = submesh.materials();
        assert(batches.size() == materials.size());

        // Render all batches in the submesh
        for (unsigned int j = 0; j < batches.size(); j++)
        {
            // Skip mostly transparent items when drawing into the shadow
            // buffer.
            // TODO: Textures with transparent parts aren't handled here
            unsigned int materialIndex = materials[j];
            if (materialIndex >= m_materials.size() || m_materials[materialIndex]->opacity() > 0.5f)
            {
                rc.drawPrimitives(*batches[j]);
            }
        }
    }

    if (boundVertexBuffer)
    {
        boundVertexBuffer->unbind();
    }

    rc.popModelView();
}
void
MeshGeometry::render(RenderContext& rc,
                     double /* clock */) const
{
    if (!m_hwBuffersCurrent)
    {
        realize();
    }

    // Track the last used material in order to avoid redundant
    // material bindings.
    unsigned int lastMaterialIndex = Submesh::DefaultMaterialIndex;

    rc.pushModelView();
    rc.scaleModelView(m_meshScale);

    // Render all submeshes
    GLVertexBuffer* boundVertexBuffer = NULL;

    for (unsigned int i = 0; i < m_submeshes.size(); ++i)
    {
        const Submesh& submesh = *m_submeshes[i];
        if (i < m_submeshBuffers.size() && m_submeshBuffers[i])
        {
            boundVertexBuffer = m_submeshBuffers[i];
            rc.bindVertexBuffer(submesh.vertices()->vertexSpec(), m_submeshBuffers[i], submesh.vertices()->stride());
        }
        else
        {
            if (boundVertexBuffer)
            {
                boundVertexBuffer->unbind();
                boundVertexBuffer = false;
            }
            rc.bindVertexArray(submesh.vertices());
        }

        const vector<PrimitiveBatch*>& batches = submesh.primitiveBatches();
        const vector<unsigned int>& materials = submesh.materials();
        assert(batches.size() == materials.size());

        // Render all batches in the submesh
        for (unsigned int j = 0; j < batches.size(); j++)
        {
            // If we have a new material, bind it
            unsigned int materialIndex = materials[j];
            if (materialIndex != lastMaterialIndex)
            {
                if (materialIndex < m_materials.size())
                {
                    rc.bindMaterial(m_materials[materialIndex].ptr());
                }
                lastMaterialIndex = materialIndex;
            }

            rc.drawPrimitives(*batches[j]);
        }
    }

    if (boundVertexBuffer)
    {
        boundVertexBuffer->unbind();
    }

    rc.popModelView();
}
Beispiel #21
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);
}
Beispiel #22
0
void BlurEffect::doBlur(const QRegion& shape, const QRect& screen, const float opacity)
{
    const QRegion expanded = expand(shape) & screen;
    const QRect r = expanded.boundingRect();

    // Upload geometry for the horizontal and vertical passes
    GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer();
    uploadGeometry(vbo, expanded, shape);
    vbo->bindArrays();

    // Create a scratch texture and copy the area in the back buffer that we're
    // going to blur into it
    GLTexture scratch(r.width(), r.height());
    scratch.setFilter(GL_LINEAR);
    scratch.setWrapMode(GL_CLAMP_TO_EDGE);
    scratch.bind();

    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r.x(), displayHeight() - r.y() - r.height(),
                        r.width(), r.height());

    // Draw the texture on the offscreen framebuffer object, while blurring it horizontally
    target->attachTexture(tex);
    GLRenderTarget::pushRenderTarget(target);

    shader->bind();
    shader->setDirection(Qt::Horizontal);
    shader->setPixelDistance(1.0 / r.width());

    // Set up the texture matrix to transform from screen coordinates
    // to texture coordinates.
    QMatrix4x4 textureMatrix;
    textureMatrix.scale(1.0 / scratch.width(), -1.0 / scratch.height(), 1);
    textureMatrix.translate(-r.x(), -scratch.height() - r.y(), 0);
    shader->setTextureMatrix(textureMatrix);

    vbo->draw(GL_TRIANGLES, 0, expanded.rectCount() * 6);

    GLRenderTarget::popRenderTarget();
    scratch.unbind();
    scratch.discard();

    // Now draw the horizontally blurred area back to the backbuffer, while
    // blurring it vertically and clipping it to the window shape.
    tex.bind();

    shader->setDirection(Qt::Vertical);
    shader->setPixelDistance(1.0 / tex.height());

    // Modulate the blurred texture with the window opacity if the window isn't opaque
    if (opacity < 1.0) {
        glEnable(GL_BLEND);
        glBlendColor(0, 0, 0, opacity);
        glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA);
    }

    // Set the up the texture matrix to transform from screen coordinates
    // to texture coordinates.
    textureMatrix.setToIdentity();
    textureMatrix.scale(1.0 / tex.width(), -1.0 / tex.height(), 1);
    textureMatrix.translate(0, -tex.height(), 0);
    shader->setTextureMatrix(textureMatrix);

    vbo->draw(GL_TRIANGLES, expanded.rectCount() * 6, shape.rectCount() * 6);
    vbo->unbindArrays();

    if (opacity < 1.0) {
        glDisable(GL_BLEND);
    }

    tex.unbind();
    shader->unbind();
}
Beispiel #23
0
void
GLScreen::glPaintTransformedOutput (const GLScreenPaintAttrib &sAttrib,
				    const GLMatrix            &transform,
				    const CompRegion          &region,
				    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);
    }
}
Beispiel #24
0
void BlurEffect::doCachedBlur(EffectWindow *w, const QRegion& region, const float opacity)
{
    const QRect screen = effects->virtualScreenGeometry();
    const QRegion blurredRegion = blurRegion(w).translated(w->pos()) & screen;
    const QRegion expanded = expand(blurredRegion) & screen;
    const QRect r = expanded.boundingRect();

    // The background texture we get is only partially valid.

    CacheEntry it = windows.find(w);
    if (it == windows.end()) {
        BlurWindowInfo bwi;
        bwi.blurredBackground = GLTexture(r.width(),r.height());
        bwi.damagedRegion = expanded;
        bwi.dropCache = false;
        bwi.windowPos = w->pos();
        it = windows.insert(w, bwi);
    } else if (it->blurredBackground.size() != r.size()) {
        it->blurredBackground = GLTexture(r.width(),r.height());
        it->dropCache = false;
        it->windowPos = w->pos();
    } else if (it->windowPos != w->pos()) {
        it->dropCache = false;
        it->windowPos = w->pos();
    }

    GLTexture targetTexture = it->blurredBackground;
    targetTexture.setFilter(GL_LINEAR);
    targetTexture.setWrapMode(GL_CLAMP_TO_EDGE);
    shader->bind();
    QMatrix4x4 textureMatrix;
    QMatrix4x4 modelViewProjectionMatrix;

    /**
     * Which part of the background texture can be updated ?
     *
     * Well this is a rather difficult question. We kind of rely on the fact, that
     * we need a bigger background region being painted before, more precisely if we want to
     * blur region A we need the background region expand(A). This business logic is basically
     * done in prePaintWindow:
     *          data.paint |= expand(damagedArea);
     *
     * Now "data.paint" gets clipped and becomes what we receive as the "region" variable
     * in this function. In theory there is now only one function that does this clipping
     * and this is paintSimpleScreen. The clipping has the effect that "damagedRegion"
     * is no longer a subset of "region" and we cannot fully validate the cache within one
     * rendering pass. If we would now update the "damageRegion & region" part of the cache
     * we would wrongly update the part of the cache that is next to the "region" border and
     * which lies within "damagedRegion", just because we cannot assume that the framebuffer
     * outside of "region" is valid. Therefore the maximal damaged region of the cache that can
     * be repainted is given by:
     *          validUpdate = damagedRegion - expand(damagedRegion - region);
     *
     * Now you may ask what is with the rest of "damagedRegion & region" that is not part
     * of "validUpdate" but also might end up on the screen. Well under the assumption
     * that only the occlusion culling can shrink "data.paint", we can control this by reducing
     * the opaque area of every window by a margin of the blurring radius (c.f. prePaintWindow).
     * This way we are sure that this area is overpainted by a higher opaque window.
     *
     * Apparently paintSimpleScreen is not the only function that can influence "region".
     * In fact every effect's paintWindow that is called before Blur::paintWindow
     * can do so (e.g. SlidingPopups). Hence we have to make the compromise that we update
     * "damagedRegion & region" of the cache but only mark "validUpdate" as valid.
     **/
    const QRegion damagedRegion = it->damagedRegion;
    const QRegion updateBackground = damagedRegion & region;
    const QRegion validUpdate = damagedRegion - expand(damagedRegion - region);

    const QRegion horizontal = validUpdate.isEmpty() ? QRegion() : (updateBackground & screen);
    const QRegion vertical   = blurredRegion & region;

    const int horizontalOffset = 0;
    const int horizontalCount = horizontal.rectCount() * 6;

    const int verticalOffset = horizontalCount;
    const int verticalCount = vertical.rectCount() * 6;

    GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer();
    uploadGeometry(vbo, horizontal, vertical);

    vbo->bindArrays();

    if (!validUpdate.isEmpty()) {
        const QRect updateRect = (expand(updateBackground) & expanded).boundingRect();
        // First we have to copy the background from the frontbuffer
        // into a scratch texture (in this case "tex").
        tex.bind();

        glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, updateRect.x(), displayHeight() - updateRect.y() - updateRect.height(),
                            updateRect.width(), updateRect.height());

        // Draw the texture on the offscreen framebuffer object, while blurring it horizontally
        target->attachTexture(targetTexture);
        GLRenderTarget::pushRenderTarget(target);

        shader->setDirection(Qt::Horizontal);
        shader->setPixelDistance(1.0 / tex.width());

        modelViewProjectionMatrix.ortho(0, r.width(), r.height(), 0 , 0, 65535);
        modelViewProjectionMatrix.translate(-r.x(), -r.y(), 0);
        shader->setModelViewProjectionMatrix(modelViewProjectionMatrix);

        // Set up the texture matrix to transform from screen coordinates
        // to texture coordinates.
        textureMatrix.scale(1.0 / tex.width(), -1.0 / tex.height(), 1);
        textureMatrix.translate(-updateRect.x(), -updateRect.height() - updateRect.y(), 0);
        shader->setTextureMatrix(textureMatrix);

        vbo->draw(GL_TRIANGLES, horizontalOffset, horizontalCount);

        GLRenderTarget::popRenderTarget();
        tex.unbind();
        // mark the updated region as valid
        it->damagedRegion -= validUpdate;
    }

    // Now draw the horizontally blurred area back to the backbuffer, while
    // blurring it vertically and clipping it to the window shape.
    targetTexture.bind();

    shader->setDirection(Qt::Vertical);
    shader->setPixelDistance(1.0 / targetTexture.height());

    // Modulate the blurred texture with the window opacity if the window isn't opaque
    if (opacity < 1.0) {
        glEnable(GL_BLEND);
        glBlendColor(0, 0, 0, opacity);
        glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA);
    }

    modelViewProjectionMatrix.setToIdentity();
    const QSize screenSize = effects->virtualScreenSize();
    modelViewProjectionMatrix.ortho(0, screenSize.width(), screenSize.height(), 0, 0, 65535);
    shader->setModelViewProjectionMatrix(modelViewProjectionMatrix);

    // Set the up the texture matrix to transform from screen coordinates
    // to texture coordinates.
    textureMatrix.setToIdentity();
    textureMatrix.scale(1.0 / targetTexture.width(), -1.0 / targetTexture.height(), 1);
    textureMatrix.translate(-r.x(), -targetTexture.height() - r.y(), 0);
    shader->setTextureMatrix(textureMatrix);

    vbo->draw(GL_TRIANGLES, verticalOffset, verticalCount);
    vbo->unbindArrays();

    if (opacity < 1.0) {
        glDisable(GL_BLEND);
    }

    targetTexture.unbind();
    shader->unbind();
}
Beispiel #25
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 ();
	    }
	}
    }
}
void LanczosFilter::performPaint(EffectWindowImpl* w, int mask, QRegion region, WindowPaintData& data)
{
    if (effects->compositingType() == KWin::OpenGLCompositing && (data.xScale() < 0.9 || data.yScale() < 0.9) &&
            KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects) {
        if (!m_inited)
            init();
        const QRect screenRect = Workspace::self()->clientArea(ScreenArea, w->screen(), w->desktop());
        // window geometry may not be bigger than screen geometry to fit into the FBO
        if (m_shader && w->width() <= screenRect.width() && w->height() <= screenRect.height()) {
            double left = 0;
            double top = 0;
            double right = w->width();
            double bottom = w->height();
            foreach (const WindowQuad & quad, data.quads) {
                // we need this loop to include the decoration padding
                left   = qMin(left, quad.left());
                top    = qMin(top, quad.top());
                right  = qMax(right, quad.right());
                bottom = qMax(bottom, quad.bottom());
            }
            double width = right - left;
            double height = bottom - top;
            if (width > screenRect.width() || height > screenRect.height()) {
                // window with padding does not fit into the framebuffer
                // so cut of the shadow
                left = 0;
                top = 0;
                width = w->width();
                height = w->height();
            }
            int tx = data.xTranslation() + w->x() + left * data.xScale();
            int ty = data.yTranslation() + w->y() + top * data.yScale();
            int tw = width * data.xScale();
            int th = height * data.yScale();
            const QRect textureRect(tx, ty, tw, th);
            const bool hardwareClipping = !(QRegion(textureRect)-region).isEmpty();

            int sw = width;
            int sh = height;

            GLTexture *cachedTexture = static_cast< GLTexture*>(w->data(LanczosCacheRole).value<void*>());
            if (cachedTexture) {
                if (cachedTexture->width() == tw && cachedTexture->height() == th) {
                    cachedTexture->bind();
                    if (hardwareClipping) {
                        glEnable(GL_SCISSOR_TEST);
                    }
                    if (ShaderManager::instance()->isValid()) {
                        glEnable(GL_BLEND);
                        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

                        const qreal rgb = data.brightness() * data.opacity();
                        const qreal a = data.opacity();

                        GLShader *shader = ShaderManager::instance()->pushShader(ShaderManager::SimpleShader);
                        shader->setUniform(GLShader::Offset, QVector2D(0, 0));
                        shader->setUniform(GLShader::ModulationConstant, QVector4D(rgb, rgb, rgb, a));
                        shader->setUniform(GLShader::Saturation, data.saturation());
                        shader->setUniform(GLShader::AlphaToOne, 0);

                        cachedTexture->render(region, textureRect, hardwareClipping);

                        ShaderManager::instance()->popShader();
                        glDisable(GL_BLEND);
                    } else {
                        prepareRenderStates(cachedTexture, data.opacity(), data.brightness(), data.saturation());
                        cachedTexture->render(region, textureRect, hardwareClipping);
                        restoreRenderStates(cachedTexture, data.opacity(), data.brightness(), data.saturation());
                    }
                    if (hardwareClipping) {
                        glDisable(GL_SCISSOR_TEST);
                    }
                    cachedTexture->unbind();
                    m_timer.start(5000, this);
                    return;
                } else {
                    // offscreen texture not matching - delete
                    delete cachedTexture;
                    cachedTexture = 0;
                    w->setData(LanczosCacheRole, QVariant());
                }
            }

            WindowPaintData thumbData = data;
            thumbData.setXScale(1.0);
            thumbData.setYScale(1.0);
            thumbData.setXTranslation(-w->x() - left);
            thumbData.setYTranslation(-w->y() - top);
            thumbData.setBrightness(1.0);
            thumbData.setOpacity(1.0);
            thumbData.setSaturation(1.0);

            // Bind the offscreen FBO and draw the window on it unscaled
            updateOffscreenSurfaces();
            GLRenderTarget::pushRenderTarget(m_offscreenTarget);

            glClearColor(0.0, 0.0, 0.0, 0.0);
            glClear(GL_COLOR_BUFFER_BIT);
            w->sceneWindow()->performPaint(mask, infiniteRegion(), thumbData);

            // Create a scratch texture and copy the rendered window into it
            GLTexture tex(sw, sh);
            tex.setFilter(GL_LINEAR);
            tex.setWrapMode(GL_CLAMP_TO_EDGE);
            tex.bind();

            glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, m_offscreenTex->height() - sh, sw, sh);

            // Set up the shader for horizontal scaling
            float dx = sw / float(tw);
            int kernelSize;
            m_shader->createKernel(dx, &kernelSize);
            m_shader->createOffsets(kernelSize, sw, Qt::Horizontal);

            m_shader->bind();
            m_shader->setUniforms();

            // Draw the window back into the FBO, this time scaled horizontally
            glClear(GL_COLOR_BUFFER_BIT);
            QVector<float> verts;
            QVector<float> texCoords;
            verts.reserve(12);
            texCoords.reserve(12);

            texCoords << 1.0 << 0.0; verts << tw  << 0.0; // Top right
            texCoords << 0.0 << 0.0; verts << 0.0 << 0.0; // Top left
            texCoords << 0.0 << 1.0; verts << 0.0 << sh;  // Bottom left
            texCoords << 0.0 << 1.0; verts << 0.0 << sh;  // Bottom left
            texCoords << 1.0 << 1.0; verts << tw  << sh;  // Bottom right
            texCoords << 1.0 << 0.0; verts << tw  << 0.0; // Top right
            GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer();
            vbo->reset();
            vbo->setData(6, 2, verts.constData(), texCoords.constData());
            vbo->render(GL_TRIANGLES);

            // At this point we don't need the scratch texture anymore
            tex.unbind();
            tex.discard();

            // create scratch texture for second rendering pass
            GLTexture tex2(tw, sh);
            tex2.setFilter(GL_LINEAR);
            tex2.setWrapMode(GL_CLAMP_TO_EDGE);
            tex2.bind();

            glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, m_offscreenTex->height() - sh, tw, sh);

            // Set up the shader for vertical scaling
            float dy = sh / float(th);
            m_shader->createKernel(dy, &kernelSize);
            m_shader->createOffsets(kernelSize, m_offscreenTex->height(), Qt::Vertical);
            m_shader->setUniforms();

            // Now draw the horizontally scaled window in the FBO at the right
            // coordinates on the screen, while scaling it vertically and blending it.
            glClear(GL_COLOR_BUFFER_BIT);

            verts.clear();

            verts << tw  << 0.0; // Top right
            verts << 0.0 << 0.0; // Top left
            verts << 0.0 << th;  // Bottom left
            verts << 0.0 << th;  // Bottom left
            verts << tw  << th;  // Bottom right
            verts << tw  << 0.0; // Top right
            vbo->setData(6, 2, verts.constData(), texCoords.constData());
            vbo->render(GL_TRIANGLES);

            tex2.unbind();
            tex2.discard();
            m_shader->unbind();

            // create cache texture
            GLTexture *cache = new GLTexture(tw, th);

            cache->setFilter(GL_LINEAR);
            cache->setWrapMode(GL_CLAMP_TO_EDGE);
            cache->bind();
            glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, m_offscreenTex->height() - th, tw, th);
            GLRenderTarget::popRenderTarget();

            if (hardwareClipping) {
                glEnable(GL_SCISSOR_TEST);
            }
            if (ShaderManager::instance()->isValid()) {
                glEnable(GL_BLEND);
                glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

                const qreal rgb = data.brightness() * data.opacity();
                const qreal a = data.opacity();

                GLShader *shader = ShaderManager::instance()->pushShader(ShaderManager::SimpleShader);
                shader->setUniform(GLShader::Offset, QVector2D(0, 0));
                shader->setUniform(GLShader::ModulationConstant, QVector4D(rgb, rgb, rgb, a));
                shader->setUniform(GLShader::Saturation, data.saturation());
                shader->setUniform(GLShader::AlphaToOne, 0);

                cache->render(region, textureRect, hardwareClipping);

                ShaderManager::instance()->popShader();
                glDisable(GL_BLEND);
            } else {
                prepareRenderStates(cache, data.opacity(), data.brightness(), data.saturation());
                cache->render(region, textureRect, hardwareClipping);
                restoreRenderStates(cache, data.opacity(), data.brightness(), data.saturation());
            }
            if (hardwareClipping) {
                glDisable(GL_SCISSOR_TEST);
            }

            cache->unbind();
            w->setData(LanczosCacheRole, QVariant::fromValue(static_cast<void*>(cache)));

            // Delete the offscreen surface after 5 seconds
            m_timer.start(5000, this);
            return;
        }
    } // if ( effects->compositingType() == KWin::OpenGLCompositing )
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);
}
Beispiel #28
0
	void * GLDevice::RDLockBuffer(RDVertexBufferP iBuffer, uint32_t iOffset, uint32_t iSize, ELockMode iAccess)
	{
		GLVertexBuffer * buffer = static_cast<GLVertexBuffer *>(iBuffer);
		return buffer->Lock(GetCurrentContext(), iOffset, iSize, ConvertLockAccess(iAccess));
	}