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); }
/* 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; }
/* 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; }
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(); }