void Texture::Init(byte* p_pData,dword p_iWidth,dword p_iHeight,dword p_iDepth,dword p_iFormat) { if(m_pxData!=nullptr) { Shut(); }; m_pxData=new TextureData(p_pData,p_iWidth,p_iHeight,p_iDepth,p_iFormat); SetFiltering(MAG_BILINEAR,MIN_BILINEAR); // Default texture filter };
bool Texture::LoadTexture(int type, const std::string& path) { int width, height; unsigned char* image = SOIL_load_image(path.c_str(), &width, &height, 0, SOIL_LOAD_RGBA); glTexImage2D(type, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image); SOIL_free_image_data(image); if(HasCallFailed()) { LogError("Failed to load " + path + " texture"); return false; } return SetFiltering(); }
/* 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; }
/* 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; }