示例#1
0
void Renderer::renderRenderData(RenderState& rstate, RenderData* render_data) {
    if (!(rstate.render_mask & render_data->render_mask()))
        return;

    // Set the states
    setRenderStates(render_data, rstate);
    if (render_data->mesh() != 0) {
        GL(renderMesh(rstate, render_data));
    }
    // Restoring to Default.
    // TODO: There's a lot of redundant state changes. If on every render face culling is being set there's no need to
    // restore defaults. Possibly later we could add a OpenGL state wrapper to avoid redundant api calls.
    restoreRenderStates(render_data);
}
示例#2
0
HRESULT Renderer::Initiate(HWND hwnd, int width, int height, bool fullscreen, bool vsync, unsigned int refRate)
{
	m_hWnd = hwnd;
	// create the IDirect3D9 object
	m_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
	if (m_pD3D == NULL)
		return E_FAIL;
	
	// get the display mode
	D3DDISPLAYMODE d3ddm;
	m_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm);

	// set the presentation parameters
	D3DPRESENT_PARAMETERS d3dpp;
	ZeroMemory(&d3dpp, sizeof(d3dpp));
	d3dpp.BackBufferWidth = width;
	d3dpp.BackBufferHeight = height;
	d3dpp.BackBufferCount = 1;
	d3dpp.BackBufferFormat = d3ddm.Format;
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	d3dpp.Windowed = !fullscreen;
	d3dpp.EnableAutoDepthStencil = true;
	d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
	d3dpp.FullScreen_RefreshRateInHz = refRate;
	if(vsync)
		d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
	else
		d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
	
	// create the device
	if (FAILED(m_pD3D->CreateDevice(D3DADAPTER_DEFAULT, 
		D3DDEVTYPE_HAL, hwnd,
		D3DCREATE_FPU_PRESERVE | D3DCREATE_HARDWARE_VERTEXPROCESSING,
		&d3dpp, &m_pD3DDevice)))
	{
		//Fallback to software rendering.
		if (FAILED(m_pD3D->CreateDevice(D3DADAPTER_DEFAULT, 
			D3DDEVTYPE_REF, hwnd,
			D3DCREATE_FPU_PRESERVE | D3DCREATE_SOFTWARE_VERTEXPROCESSING,
			&d3dpp, &m_pD3DDevice)))
		{
			return E_FAIL;
		}
	}

	m_pD3DDevice->GetRenderTarget(0, &m_pOriginalBackBuffer);
	m_pD3DDevice->GetDepthStencilSurface(&m_pOriginalDepthStencil);

	//Set default render attributes.
	m_bDepthBufferRead = true;
	m_bDepthBufferWrite = true;
	m_bBlendEnable = true;
	m_fConstantOpacity = 1.0f;
	m_bZEnable = true;
	m_bFogEnable = false;
	m_nWidth = width;
	m_nHeight = height;
	m_nTargetHeight = height;
	m_nTargetWidth = width;
	m_bRenderToBackBuffer = true;

	restoreRenderStates();

	gTextureManager = new TextureManager();

	m_listVertexBuffer = NULL;
	m_listIndexBuffer = NULL;

	int vert_count;
	int byte_count;
	int ind_count;
	HRESULT hres;
	int sprite_count = 3 * (int)GetCoordOffsetInv() * (int)GetCoordOffsetInv();
	vert_count=6;//BillboardSprite::GetNumVerticesStatic();
	byte_count = vert_count*sizeof(RenderVertexTL) * sprite_count;
	m_nLengthVertexBuffer = vert_count * sprite_count;
	hres = m_pD3DDevice->CreateVertexBuffer(	
												byte_count, //length
												D3DUSAGE_WRITEONLY, //usage flags
												RenderVertexTL::FVF, //FVF
												D3DPOOL_MANAGED, //Pool
												&m_listVertexBuffer, //vertex buffer to be used.
												NULL //should be null?
											);

	if(FAILED(hres))
	{
		switch(hres)
		{
		case D3DERR_INVALIDCALL:
			DEBUGPRINTF("Invalid call in CreateVertexBuffer\n");
			break;
		case D3DERR_OUTOFVIDEOMEMORY:
			DEBUGPRINTF("Out of video memory for CreateVertexBuffer\n");
			break;
		case E_OUTOFMEMORY:
			DEBUGPRINTF("Out of memory for CreateVertexBuffer\n");
			break;
		}
		DEBUGPRINTF("%d bytes into vertex buffer fails\n", hres);
		return E_FAIL;
	}
	ind_count=BillboardSprite::GetNumIndicesStatic();
	byte_count = ind_count*sizeof(int) * sprite_count;
	m_nLengthIndexBuffer = ind_count * sprite_count;
	hres = m_pD3DDevice->CreateIndexBuffer(	
												byte_count, //length
												D3DUSAGE_WRITEONLY, //usage flags
												D3DFMT_INDEX16, //format of indices
												D3DPOOL_MANAGED, //Pool
												&m_listIndexBuffer, //vertex buffer to be used.
												NULL //should be null?
											);

	if(FAILED(hres))
	{
		switch(hres)
		{
		case D3DERR_INVALIDCALL:
			DEBUGPRINTF("Invalid call in CreateVertexBuffer\n");
			break;
		case D3DERR_OUTOFVIDEOMEMORY:
			DEBUGPRINTF("Out of video memory for CreateVertexBuffer\n");
			break;
		case E_OUTOFMEMORY:
			DEBUGPRINTF("Out of memory for CreateVertexBuffer\n");
			break;
		}
		DEBUGPRINTF("%d bytes into vertex buffer fails\n", hres);
		return E_FAIL;
	}

	DEBUGPRINTF("Size of input: %d\n", sizeof(RenderVertexTL[4]));
	m_nCurrentSprite = 0;
	m_uNumTriangles = 0;
	return S_OK;
}
示例#3
0
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 )