Esempio n. 1
0
void CDirect3D::SetViewport()
{
	D3DXMATRIX matIdentity;
	D3DXMATRIX matProjection;

	D3DXMatrixOrthoOffCenterLH(&matProjection,0.0f,1.0f,0.0f,1.0f,0.0f,1.0f);
	D3DXMatrixIdentity(&matIdentity);
	pDevice->SetTransform(D3DTS_WORLD,&matIdentity);
	pDevice->SetTransform(D3DTS_VIEW,&matIdentity);
	pDevice->SetTransform(D3DTS_PROJECTION,&matProjection);

	SetShaderVars(true);

	RECT drawRect = CalculateDisplayRect(afterRenderWidth,afterRenderHeight,dPresentParams.BackBufferWidth,dPresentParams.BackBufferHeight);
	D3DVIEWPORT9 viewport;
	viewport.X = drawRect.left;
	viewport.Y = drawRect.top;
	viewport.Height = drawRect.bottom - drawRect.top;
	viewport.Width = drawRect.right - drawRect.left;
	viewport.MinZ = 0.0f;
	viewport.MaxZ = 1.0f;
	HRESULT hr = pDevice->SetViewport(&viewport);

	SetupVertices();
}
Esempio n. 2
0
void gp2x_set_video_mode(struct osd_bitmap *bitmap, int bpp,int width,int height)
{
	surface_width = width;
	surface_height = height;

	gp2x_screen32 = (uint32_t *) calloc(1, surface_width*surface_height*4);

	if (texture) SDL_DestroyTexture(texture);
	texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, surface_width, surface_height);

	CalculateDisplayRect(window_width, window_height, surface_width, surface_height, &displayRect);
}
Esempio n. 3
0
bool COpenGL::ChangeRenderSize(unsigned int newWidth, unsigned int newHeight)
{
	RECT displayRect, windowSize;
	if(newWidth==0||newHeight==0) {
		GetClientRect(hWnd,&windowSize);
		newWidth = windowSize.right;
		newHeight = windowSize.bottom;
	}
	displayRect=CalculateDisplayRect(afterRenderWidth,afterRenderHeight,newWidth,newHeight);
	glViewport(displayRect.left,newHeight-displayRect.bottom,displayRect.right-displayRect.left,displayRect.bottom-displayRect.top);
	SetupVertices();
	return true;
}
Esempio n. 4
0
void wOGLViewportCallback(int source_width, int source_height,
	int viewport_x, int viewport_y,
	int viewport_width, int viewport_height,
	int *out_dst_x, int *out_dst_y,
	int *out_dst_width, int *out_dst_height)
{
	/* get window size here instead of using viewport passed in - we limited the viewport before the glsl render
	   call already, this is simply to position smaller outputs correctly in the actual viewport
	 */
	RECT windowSize;
	GetClientRect(GUI.hWnd, &windowSize);
	RECT displayRect = CalculateDisplayRect(source_width, source_height, windowSize.right, windowSize.bottom);
	*out_dst_x = displayRect.left;
	*out_dst_y = displayRect.top;
	*out_dst_width = displayRect.right - displayRect.left;
	*out_dst_height = displayRect.bottom - displayRect.top;
}
Esempio n. 5
0
void COpenGL::Render(SSurface Src)
{
	SSurface Dst;
	RECT dstRect;
	unsigned int newFilterScale;
	GLenum error;

	if(!initDone) return;

	//create a new draw surface if the filter scale changes
	//at least factor 2 so we can display unscaled hi-res images
	newFilterScale = max(2,max(GetFilterScale(GUI.ScaleHiRes),GetFilterScale(GUI.Scale)));
	if(newFilterScale!=filterScale) {
		ChangeDrawSurfaceSize(newFilterScale);
	}

	if(pboFunctionsLoaded) {
		glBindBuffer(GL_PIXEL_UNPACK_BUFFER, drawBuffer);
		Dst.Surface = (unsigned char *)glMapBuffer(GL_PIXEL_UNPACK_BUFFER,GL_READ_WRITE);
	} else {
		Dst.Surface = noPboBuffer;
	}
	Dst.Height = quadTextureSize;
	Dst.Width = quadTextureSize;
	Dst.Pitch = quadTextureSize * 2;

	RenderMethod (Src, Dst, &dstRect);
	if(!Settings.AutoDisplayMessages) {
		WinSetCustomDisplaySurface((void *)Dst.Surface, Dst.Pitch/2, dstRect.right-dstRect.left, dstRect.bottom-dstRect.top, GetFilterScale(CurrentScale));
		S9xDisplayMessages ((uint16*)Dst.Surface, Dst.Pitch/2, dstRect.right-dstRect.left, dstRect.bottom-dstRect.top, GetFilterScale(CurrentScale));
	}

	if(pboFunctionsLoaded)
		glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);

	if(afterRenderHeight != dstRect.bottom || afterRenderWidth != dstRect.right) {
		afterRenderHeight = dstRect.bottom;
		afterRenderWidth = dstRect.right;

		ChangeRenderSize(0,0);
	}

	glBindTexture(GL_TEXTURE_2D,drawTexture);
	glPixelStorei(GL_UNPACK_ROW_LENGTH, quadTextureSize);
	glTexSubImage2D (GL_TEXTURE_2D,0,0,0,dstRect.right-dstRect.left,dstRect.bottom-dstRect.top,GL_RGB,GL_UNSIGNED_SHORT_5_6_5,pboFunctionsLoaded?0:noPboBuffer);

	if(pboFunctionsLoaded)
		glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);

	if (shader_type != OGL_SHADER_NONE) {

		if(shader_type == OGL_SHADER_GLSL) {
			GLint location;

			float inputSize[2] = { (float)afterRenderWidth, (float)afterRenderHeight };
			RECT windowSize;
			GetClientRect(hWnd,&windowSize);
			float outputSize[2] = {(float)(GUI.Stretch?windowSize.right:afterRenderWidth),
								(float)(GUI.Stretch?windowSize.bottom:afterRenderHeight) };
			float textureSize[2] = { (float)quadTextureSize, (float)quadTextureSize };
			float frameCnt = (float)++frameCount;
			location = glGetUniformLocation (shaderProgram, "rubyInputSize");
			glUniform2fv (location, 1, inputSize);

			location = glGetUniformLocation (shaderProgram, "rubyOutputSize");
			glUniform2fv (location, 1, outputSize);

			location = glGetUniformLocation (shaderProgram, "rubyTextureSize");
			glUniform2fv (location, 1, textureSize);
		} else if(shader_type == OGL_SHADER_CG) {
			xySize inputSize = { (float)afterRenderWidth, (float)afterRenderHeight };
			RECT windowSize, displayRect;
			GetClientRect(hWnd,&windowSize);
			xySize xywindowSize = { (double)windowSize.right, (double)windowSize.bottom };
			//Get maximum rect respecting AR setting
			displayRect=CalculateDisplayRect(windowSize.right,windowSize.bottom,windowSize.right,windowSize.bottom);
			xySize viewportSize = { (double)(displayRect.right - displayRect.left),
				                    (double)(displayRect.bottom - displayRect.top) };
			xySize textureSize = { (double)quadTextureSize, (double)quadTextureSize };
			cgShader->Render(drawTexture, textureSize, inputSize, viewportSize, xywindowSize);
		}
    }

	if(GUI.BilinearFilter) {
		glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	} else {
		glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	}

	glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
	glClear(GL_COLOR_BUFFER_BIT);
	glDrawArrays (GL_QUADS, 0, 4);

	glFlush();
	SwapBuffers(hDC);
}
Esempio n. 6
0
/*  CDirect3D::Render
does the actual rendering, changes the draw surface if necessary and recalculates
the vertex information if filter output size changes
IN:
Src		-	the input surface
*/
void CDirect3D::Render(SSurface Src)
{
	SSurface Dst;
	RECT dstRect;
	unsigned int newFilterScale;
	D3DLOCKED_RECT lr;
	D3DLOCKED_RECT lrConv;
	HRESULT hr;

	if(!init_done) return;

	//create a new draw surface if the filter scale changes
	//at least factor 2 so we can display unscaled hi-res images
	newFilterScale = max(2,max(GetFilterScale(GUI.ScaleHiRes),GetFilterScale(GUI.Scale)));
	if(newFilterScale!=filterScale) {
		ChangeDrawSurfaceSize(newFilterScale);
	}

	if(FAILED(hr = pDevice->TestCooperativeLevel())) {
		switch(hr) {
			case D3DERR_DEVICELOST:		//do no rendering until device is restored
				return;
			case D3DERR_DEVICENOTRESET: //we can reset now
                if(!IsIconic(dPresentParams.hDeviceWindow))
				    ResetDevice();
				return;
			default:
				DXTRACE_ERR_MSGBOX(TEXT("Internal driver error"), hr);
				return;
		}
	}

	//BlankTexture(drawSurface);
	if(FAILED(hr = drawSurface->LockRect(0, &lr, NULL, 0))) {
		DXTRACE_ERR_MSGBOX(TEXT("Unable to lock texture"), hr);
		return;
	} else {
		Dst.Surface = (unsigned char *)lr.pBits;
		Dst.Height = quadTextureSize;
		Dst.Width = quadTextureSize;
		Dst.Pitch = lr.Pitch;

		RenderMethod (Src, Dst, &dstRect);
		if(!Settings.AutoDisplayMessages) {
			WinSetCustomDisplaySurface((void *)Dst.Surface, Dst.Pitch/2, dstRect.right-dstRect.left, dstRect.bottom-dstRect.top, GetFilterScale(CurrentScale));
			S9xDisplayMessages ((uint16*)Dst.Surface, Dst.Pitch/2, dstRect.right-dstRect.left, dstRect.bottom-dstRect.top, GetFilterScale(CurrentScale));
		}

		drawSurface->UnlockRect(0);
	}

	if (!GUI.Stretch || GUI.AspectRatio) {
		Clear();
	}

	//if the output size of the render method changes we need to update the viewport
	if(afterRenderHeight != dstRect.bottom || afterRenderWidth != dstRect.right) {
		afterRenderHeight = dstRect.bottom;
		afterRenderWidth = dstRect.right;
		SetViewport();
	}

	pDevice->SetTexture(0, drawSurface);
	pDevice->SetVertexDeclaration(vertexDeclaration);
	pDevice->SetStreamSource(0,vertexBuffer,0,sizeof(VERTEX));

	if(shader_type == D3D_SHADER_CG) {
		RECT displayRect;
		//Get maximum rect respecting AR setting
		displayRect=CalculateDisplayRect(dPresentParams.BackBufferWidth,dPresentParams.BackBufferHeight,
										dPresentParams.BackBufferWidth,dPresentParams.BackBufferHeight);
		cgShader->Render(drawSurface,
			XMFLOAT2((float)quadTextureSize, (float)quadTextureSize),
			XMFLOAT2((float)afterRenderWidth, (float)afterRenderHeight),
			XMFLOAT2((float)(displayRect.right - displayRect.left),
								(float)(displayRect.bottom - displayRect.top)),
			XMFLOAT2((float)dPresentParams.BackBufferWidth, (float)dPresentParams.BackBufferHeight));
	}

	SetFiltering();

	pDevice->SetVertexDeclaration(vertexDeclaration);

	pDevice->BeginScene();
	pDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,2);
	pDevice->EndScene();

	pDevice->Present(NULL, NULL, NULL, NULL);

	if (GUI.ReduceInputLag)
	{
		IDirect3DSurface9 *surface;
		RECT r = { 0, 0, 2, 2 };

		if (pDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &surface) == D3D_OK)
		{
			if (surface->LockRect(&lr, &r, D3DLOCK_READONLY) == D3D_OK)
			{
				surface->UnlockRect();
			}
			surface->Release();
		}
	}

    return;
}
Esempio n. 7
0
void CGLCG::Render(GLuint &origTex, xySize textureSize, xySize inputSize, xySize viewportSize, xySize windowSize)
{
	GLenum error;
	frameCnt++;
	CGprofile vertexProfile, fragmentProfile;

	if(!shaderLoaded)
		return;

	vertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX);
	fragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);

	cgGLEnableProfile(vertexProfile);
	cgGLEnableProfile(fragmentProfile);	

	/* set up our dummy pass for easier loop code
	*/
	shaderPasses[0].tex = origTex;
	shaderPasses[0].outputSize = inputSize;
	shaderPasses[0].textureSize = textureSize;

	/* loop through all real passes
	*/
	for(int i=1;i<shaderPasses.size();i++) {
		switch(shaderPasses[i].scaleParams.scaleTypeX) {
			case CG_SCALE_ABSOLUTE:
				shaderPasses[i].outputSize.x = (double)shaderPasses[i].scaleParams.absX;
				break;
			case CG_SCALE_SOURCE:
				shaderPasses[i].outputSize.x = shaderPasses[i-1].outputSize.x * shaderPasses[i].scaleParams.scaleX;
				break;
			case CG_SCALE_VIEWPORT:
				shaderPasses[i].outputSize.x = viewportSize.x * shaderPasses[i].scaleParams.scaleX;
				break;
			default:
				shaderPasses[i].outputSize.x = viewportSize.x;
		}
		switch(shaderPasses[i].scaleParams.scaleTypeY) {
			case CG_SCALE_ABSOLUTE:
				shaderPasses[i].outputSize.y = (double)shaderPasses[i].scaleParams.absY;
				break;
			case CG_SCALE_SOURCE:
				shaderPasses[i].outputSize.y = shaderPasses[i-1].outputSize.y * shaderPasses[i].scaleParams.scaleY;
				break;
			case CG_SCALE_VIEWPORT:
				shaderPasses[i].outputSize.y = viewportSize.y * shaderPasses[i].scaleParams.scaleY;
				break;
			default:
				shaderPasses[i].outputSize.y = viewportSize.y;
		}
		/* use next power of two in both directions
		*/
		float texSize = npot(max(shaderPasses[i].outputSize.x,shaderPasses[i].outputSize.y));
		shaderPasses[i].textureSize.x = shaderPasses[i].textureSize.y = texSize;

		/* set size of output texture
		*/
		glBindTexture(GL_TEXTURE_2D,shaderPasses[i].tex);
        glTexImage2D(GL_TEXTURE_2D,0,(shaderPasses[i].floatFbo?GL_RGBA32F:GL_RGBA),(unsigned int)shaderPasses[i].textureSize.x,
			(unsigned int)shaderPasses[i].textureSize.y,0,GL_RGBA,GL_UNSIGNED_INT_8_8_8_8,NULL);

		/* viewport determines the area we render into the output texture
		*/
		glViewport(0,0,shaderPasses[i].outputSize.x,shaderPasses[i].outputSize.y);

		/* set up framebuffer and attach output texture
		*/
		glBindFramebuffer(GL_FRAMEBUFFER,shaderPasses[i].fbo);
		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, shaderPasses[i].tex, 0);

		/* set up input texture (output of previous pass) and apply filter settings
		*/
		glBindTexture(GL_TEXTURE_2D,shaderPasses[i-1].tex);
		glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)shaderPasses[i-1].textureSize.x);
		glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
			shaderPasses[i].linearFilter?GL_LINEAR:GL_NEAREST);
		glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
			shaderPasses[i].linearFilter?GL_LINEAR:GL_NEAREST);

		/* calculate tex coords first since we pass them to the shader
		*/
		setTexCoords(i,shaderPasses[i-1].outputSize,shaderPasses[i-1].textureSize);

		setShaderVars(i);

		cgGLBindProgram(shaderPasses[i].cgVertexProgram);
		cgGLBindProgram(shaderPasses[i].cgFragmentProgram);

		glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
		glClear(GL_COLOR_BUFFER_BIT);
		glDrawArrays (GL_QUADS, 0, 4);

		/* reset client states enabled during setShaderVars
		*/
		resetAttribParams();

	}

	/* disable framebuffer
	*/
	glBindFramebuffer(GL_FRAMEBUFFER,0);

	/* set last PREV texture as original, push current texture and
	   sizes to the front of the PREV deque and make sure the new
	   original texture has the same size as the old one
	*/

	origTex = prevPasses.back().tex;
	prevPasses.pop_back();

	prevPass pass;
	pass.videoSize = inputSize;
	pass.textureSize = textureSize;
	pass.tex = shaderPasses[0].tex;
	memcpy(pass.texCoords,shaderPasses[1].texcoords,sizeof(pass.texCoords));
	prevPasses.push_front(pass);
	glBindTexture(GL_TEXTURE_2D,origTex);
	glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,textureSize.x,textureSize.y,0,GL_RGB,GL_UNSIGNED_SHORT_5_6_5,NULL);

	/* bind output of last pass to be rendered on the backbuffer
	*/
	glBindTexture(GL_TEXTURE_2D,shaderPasses.back().tex);
	glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)shaderPasses.back().textureSize.x);

	/* calculate and apply viewport and texture coordinates to
	   that will be used in the main ogl code
	*/
	RECT displayRect=CalculateDisplayRect(shaderPasses.back().outputSize.x,shaderPasses.back().outputSize.y,windowSize.x,windowSize.y);
	glViewport(displayRect.left,windowSize.y-displayRect.bottom,displayRect.right-displayRect.left,displayRect.bottom-displayRect.top);	
	setTexCoords(shaderPasses.size()-1,shaderPasses.back().outputSize,shaderPasses.back().textureSize,true);

	/* render to backbuffer without shaders
	*/
	cgGLDisableProfile(vertexProfile);
	cgGLDisableProfile(fragmentProfile);
}
Esempio n. 8
0
/*  CDirect3D::Render
does the actual rendering, changes the draw surface if necessary and recalculates
the vertex information if filter output size changes
IN:
Src		-	the input surface
*/
void CDirect3D::Render(SSurface Src)
{
	SSurface Dst;
	RECT dstRect;
	unsigned int newFilterScale;
	D3DLOCKED_RECT lr;
	D3DLOCKED_RECT lrConv;
	HRESULT hr;

	if(!init_done) return;

	//create a new draw surface if the filter scale changes
	//at least factor 2 so we can display unscaled hi-res images
	newFilterScale = max(2,max(GetFilterScale(GUI.ScaleHiRes),GetFilterScale(GUI.Scale)));
	if(newFilterScale!=filterScale) {
		ChangeDrawSurfaceSize(newFilterScale);
	}

	if(FAILED(hr = pDevice->TestCooperativeLevel())) {
		switch(hr) {
			case D3DERR_DEVICELOST:		//do no rendering until device is restored
				return;
			case D3DERR_DEVICENOTRESET: //we can reset now
				ResetDevice();
				return;
			default:
				DXTRACE_ERR_MSGBOX( TEXT("Internal driver error"), hr);
				return;
		}
	}

	//BlankTexture(drawSurface);
	if(FAILED(hr = drawSurface->LockRect(0, &lr, NULL, 0))) {
		DXTRACE_ERR_MSGBOX( TEXT("Unable to lock texture"), hr);
		return;
	} else {
		Dst.Surface = (unsigned char *)lr.pBits;
		Dst.Height = quadTextureSize;
		Dst.Width = quadTextureSize;
		Dst.Pitch = lr.Pitch;

		RenderMethod (Src, Dst, &dstRect);
		if(!Settings.AutoDisplayMessages) {
			WinSetCustomDisplaySurface((void *)Dst.Surface, Dst.Pitch/2, dstRect.right-dstRect.left, dstRect.bottom-dstRect.top, GetFilterScale(CurrentScale));
			S9xDisplayMessages ((uint16*)Dst.Surface, Dst.Pitch/2, dstRect.right-dstRect.left, dstRect.bottom-dstRect.top, GetFilterScale(CurrentScale));
		}

		drawSurface->UnlockRect(0);
	}

	if(!GUI.Stretch||GUI.AspectRatio)
		pDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);

	//if the output size of the render method changes we need to update the viewport
	if(afterRenderHeight != dstRect.bottom || afterRenderWidth != dstRect.right) {
		afterRenderHeight = dstRect.bottom;
		afterRenderWidth = dstRect.right;
		SetViewport();
	}

	pDevice->SetTexture(0, drawSurface);
	pDevice->SetVertexDeclaration(vertexDeclaration);
	pDevice->SetStreamSource(0,vertexBuffer,0,sizeof(VERTEX));

	if (shader_type == D3D_SHADER_HLSL) {
		SetShaderVars();
		SetFiltering();

		UINT passes;
		pDevice->BeginScene();
		hr = effect->Begin(&passes, 0);
		for(UINT pass = 0; pass < passes; pass++ ) {
			effect->BeginPass(pass);
			pDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,2);
			effect->EndPass();
		}
		effect->End();
		pDevice->EndScene();

	} else {
		if(shader_type == D3D_SHADER_CG) {
			RECT displayRect;
			//Get maximum rect respecting AR setting
			displayRect=CalculateDisplayRect(dPresentParams.BackBufferWidth,dPresentParams.BackBufferHeight,
											dPresentParams.BackBufferWidth,dPresentParams.BackBufferHeight);
			cgShader->Render(drawSurface,
				D3DXVECTOR2((float)quadTextureSize, (float)quadTextureSize),
				D3DXVECTOR2((float)afterRenderWidth, (float)afterRenderHeight),
				D3DXVECTOR2((float)(displayRect.right - displayRect.left),
									(float)(displayRect.bottom - displayRect.top)),
				D3DXVECTOR2((float)dPresentParams.BackBufferWidth, (float)dPresentParams.BackBufferHeight));
		}

		SetFiltering();

		pDevice->SetVertexDeclaration(vertexDeclaration);

		pDevice->BeginScene();
		pDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,2);
		pDevice->EndScene();
	}

	pDevice->Present(NULL, NULL, NULL, NULL);

    return;
}
Esempio n. 9
0
void COpenGL::Render(SSurface Src)
{
	SSurface Dst;
	RECT dstRect;
	unsigned int newFilterScale;
	GLenum error;

	if(!initDone) return;

	//create a new draw surface if the filter scale changes
	dstRect = GetFilterOutputSize(Src);
	if(outTextureWidth != dstRect.right || outTextureHeight != dstRect.bottom)
		ChangeDrawSurfaceSize(dstRect.right, dstRect.bottom);

	if(pboFunctionsLoaded) {
		glBindBuffer(GL_PIXEL_UNPACK_BUFFER, drawBuffer);
		Dst.Surface = (unsigned char *)glMapBuffer(GL_PIXEL_UNPACK_BUFFER,GL_READ_WRITE);
	} else {
		Dst.Surface = noPboBuffer;
	}
	Dst.Height = outTextureHeight;
	Dst.Width = outTextureWidth;
	Dst.Pitch = outTextureWidth * 2;

	RenderMethod (Src, Dst, &dstRect);
	if(!Settings.AutoDisplayMessages) {
		WinSetCustomDisplaySurface((void *)Dst.Surface, Dst.Pitch/2, dstRect.right-dstRect.left, dstRect.bottom-dstRect.top, GetFilterScale(CurrentScale));
		S9xDisplayMessages ((uint16*)Dst.Surface, Dst.Pitch/2, dstRect.right-dstRect.left, dstRect.bottom-dstRect.top, GetFilterScale(CurrentScale));
	}

	if(pboFunctionsLoaded)
		glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);

	if(afterRenderHeight != dstRect.bottom || afterRenderWidth != dstRect.right) {
		afterRenderHeight = dstRect.bottom;
		afterRenderWidth = dstRect.right;

		ChangeRenderSize(0,0);
	}

	glBindTexture(GL_TEXTURE_2D,drawTexture);
	glPixelStorei(GL_UNPACK_ROW_LENGTH, outTextureWidth);
	glTexSubImage2D (GL_TEXTURE_2D,0,0,0,dstRect.right-dstRect.left,dstRect.bottom-dstRect.top,GL_RGB,GL_UNSIGNED_SHORT_5_6_5,pboFunctionsLoaded?0:noPboBuffer);

	if(pboFunctionsLoaded)
		glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);

	RECT windowSize, displayRect;
	GetClientRect(hWnd, &windowSize);
	//Get maximum rect respecting AR setting
	displayRect = CalculateDisplayRect(windowSize.right, windowSize.bottom, windowSize.right, windowSize.bottom);

	// GLSL class does all the rendering, no output needed
	if (shader_type == OGL_SHADER_GLSL) {
		glslShader->render(drawTexture, afterRenderWidth, afterRenderHeight, displayRect.left, displayRect.top, displayRect.right - displayRect.left, displayRect.bottom - displayRect.top, wOGLViewportCallback);
	}
	else { // for CG shaders and old style .shader files the last pass is done here, same as no shader
		if(shader_type == OGL_SHADER_CG) {
			xySize inputSize = { (float)afterRenderWidth, (float)afterRenderHeight };
			xySize xywindowSize = { (double)windowSize.right, (double)windowSize.bottom };
			xySize viewportSize = { (double)(displayRect.right - displayRect.left),
				                    (double)(displayRect.bottom - displayRect.top) };
			xySize textureSize = { (double)outTextureWidth, (double)outTextureHeight };
			cgShader->Render(drawTexture, textureSize, inputSize, viewportSize, xywindowSize);
		}
		else if (shader_type == OGL_SHADER_GLSL_OLD) {
			GLint location;

			float inputSize[2] = { (float)afterRenderWidth, (float)afterRenderHeight };
			float outputSize[2] = { (float)(GUI.Stretch ? windowSize.right : afterRenderWidth),
				(float)(GUI.Stretch ? windowSize.bottom : afterRenderHeight) };
			float textureSize[2] = { (float)outTextureWidth, (float)outTextureHeight };
			float frameCnt = (float)++frameCount;
			location = glGetUniformLocation(shaderProgram, "rubyInputSize");
			glUniform2fv(location, 1, inputSize);

			location = glGetUniformLocation(shaderProgram, "rubyOutputSize");
			glUniform2fv(location, 1, outputSize);

			location = glGetUniformLocation(shaderProgram, "rubyTextureSize");
			glUniform2fv(location, 1, textureSize);
		}
		if (Settings.BilinearFilter) {
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		}
		else {
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
		}

		glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
		glClear(GL_COLOR_BUFFER_BIT);
		glDrawArrays(GL_QUADS, 0, 4);
    }

	glFlush();
	SwapBuffers(hDC);
	if (GUI.ReduceInputLag)
		glFinish();
}
Esempio n. 10
0
void CD3DCG::Render(LPDIRECT3DTEXTURE9 &origTex, D3DXVECTOR2 textureSize,
					D3DXVECTOR2 inputSize, D3DXVECTOR2 viewportSize, D3DXVECTOR2 windowSize)
{
	LPDIRECT3DSURFACE9 pRenderSurface = NULL,pBackBuffer = NULL;
	frameCnt++;

	if(!shaderLoaded)
		return;

	/* save back buffer render target
	*/
	pDevice->GetRenderTarget(0,&pBackBuffer);	

	/* pass 0 represents the original texture
	*/
	shaderPasses[0].tex = origTex;
	shaderPasses[0].outputSize = inputSize;
	shaderPasses[0].textureSize = textureSize;

	calculateMatrix();	

	for(int i=1;i<shaderPasses.size();i++) {
		switch(shaderPasses[i].scaleParams.scaleTypeX) {
			case CG_SCALE_ABSOLUTE:
				shaderPasses[i].outputSize.x = (double)shaderPasses[i].scaleParams.absX;
				break;
			case CG_SCALE_SOURCE:
				shaderPasses[i].outputSize.x = shaderPasses[i-1].outputSize.x * shaderPasses[i].scaleParams.scaleX;
				break;
			case CG_SCALE_VIEWPORT:
				shaderPasses[i].outputSize.x = viewportSize.x * shaderPasses[i].scaleParams.scaleX;
				break;
			default:
				shaderPasses[i].outputSize.x = viewportSize.x;
		}
		switch(shaderPasses[i].scaleParams.scaleTypeY) {
			case CG_SCALE_ABSOLUTE:
				shaderPasses[i].outputSize.y = (double)shaderPasses[i].scaleParams.absY;
				break;
			case CG_SCALE_SOURCE:
				shaderPasses[i].outputSize.y = shaderPasses[i-1].outputSize.y * shaderPasses[i].scaleParams.scaleY;
				break;
			case CG_SCALE_VIEWPORT:
				shaderPasses[i].outputSize.y = viewportSize.y * shaderPasses[i].scaleParams.scaleY;
				break;
			default:
				shaderPasses[i].outputSize.y = viewportSize.y;
		}
		float texSize = npot(max(shaderPasses[i].outputSize.x,shaderPasses[i].outputSize.y));
		
		/* make sure the render target exists and has an appropriate size,
		   then set as current render target with last pass as source
		*/
		ensureTextureSize(shaderPasses[i].tex,shaderPasses[i].textureSize,D3DXVECTOR2(texSize,texSize),true);
		shaderPasses[i].tex->GetSurfaceLevel(0,&pRenderSurface);
		pDevice->SetTexture(0, shaderPasses[i-1].tex);
		pDevice->SetRenderTarget(0,pRenderSurface);
		pRenderSurface->Release();

		/* set vertex declaration of current pass, update vertex
		   buffer and set base streams
		*/
		pDevice->SetVertexDeclaration(shaderPasses[i].vertexDeclaration);
		setVertexStream(shaderPasses[i].vertexBuffer,
			shaderPasses[i-1].outputSize,shaderPasses[i-1].textureSize,shaderPasses[i].outputSize);
		pDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER);
		pDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);
		pDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, shaderPasses[i].linearFilter?D3DTEXF_LINEAR:D3DTEXF_POINT);
		pDevice->SetSamplerState(0, D3DSAMP_MINFILTER, shaderPasses[i].linearFilter?D3DTEXF_LINEAR:D3DTEXF_POINT);

		/* shader vars need to be set after the base vertex streams
		   have been set so they can override them
		*/
		setShaderVars(i);

		cgD3D9BindProgram(shaderPasses[i].cgVertexProgram);
		checkForCgError("Binding vertex program");
		cgD3D9BindProgram(shaderPasses[i].cgFragmentProgram);
		checkForCgError("Binding fragment program");
		
		/* viewport defines output size
		*/
		setViewport(0,0,shaderPasses[i].outputSize.x,shaderPasses[i].outputSize.y);

		pDevice->BeginScene();
		pDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,2);
		pDevice->EndScene();
	}

	/* take oldes PREV out of deque, make sure it has
	   the same size as the current texture and
	   then set it up as new original texture
	*/
	prevPass &oldestPrev = prevPasses.back();
	ensureTextureSize(oldestPrev.tex,oldestPrev.textureSize,textureSize,false);
	if(oldestPrev.vertexBuffer)
		oldestPrev.vertexBuffer->Release();
	origTex = oldestPrev.tex;
	prevPasses.pop_back();
	
	/* push current original with corresponding vertex
	   buffer to front of PREV deque
	*/
	shaderPasses[0].vertexBuffer = shaderPasses[1].vertexBuffer;
	prevPasses.push_front(prevPass(shaderPasses[0]));
	
	/* create new vertex buffer so that next render call
	   will not overwrite the PREV
	*/
	pDevice->CreateVertexBuffer(sizeof(VERTEX)*4,D3DUSAGE_WRITEONLY,0,D3DPOOL_MANAGED,&shaderPasses[1].vertexBuffer,NULL);
	
	/* set up last pass texture, backbuffer and viewport
	   for final display pass without shaders
	*/
	pDevice->SetTexture(0, shaderPasses.back().tex);
	pDevice->SetRenderTarget(0,pBackBuffer);
	pBackBuffer->Release();
	RECT displayRect=CalculateDisplayRect(shaderPasses.back().outputSize.x,shaderPasses.back().outputSize.y,windowSize.x,windowSize.y);
	setViewport(displayRect.left,displayRect.top,displayRect.right - displayRect.left,displayRect.bottom - displayRect.top);
	setVertexStream(shaderPasses.back().vertexBuffer,
		shaderPasses.back().outputSize,shaderPasses.back().textureSize,
		D3DXVECTOR2(displayRect.right - displayRect.left,displayRect.bottom - displayRect.top));
	pDevice->SetVertexShader(NULL);
	pDevice->SetPixelShader(NULL);
}