mirror of
https://github.com/reactos/wine.git
synced 2024-11-29 22:50:43 +00:00
wined3d: Implement ColorFill using FBOs, if they're being used.
This commit is contained in:
parent
e49c480820
commit
e0a94b906c
@ -4974,6 +4974,105 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DeletePatch(IWineD3DDevice *iface, UINT
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
static IWineD3DSwapChain *get_swapchain(IWineD3DSurface *target) {
|
||||
HRESULT hr;
|
||||
IWineD3DSwapChain *swapchain;
|
||||
|
||||
hr = IWineD3DSurface_GetContainer(target, &IID_IWineD3DSwapChain, (void **)&swapchain);
|
||||
if (SUCCEEDED(hr)) {
|
||||
IWineD3DSwapChain_Release((IUnknown *)swapchain);
|
||||
return swapchain;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void bind_fbo(IWineD3DDevice *iface, GLenum target, GLuint *fbo) {
|
||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
||||
|
||||
if (!*fbo) {
|
||||
GL_EXTCALL(glGenFramebuffersEXT(1, fbo));
|
||||
checkGLcall("glGenFramebuffersEXT()");
|
||||
}
|
||||
GL_EXTCALL(glBindFramebufferEXT(target, *fbo));
|
||||
checkGLcall("glBindFramebuffer()");
|
||||
}
|
||||
|
||||
static void attach_surface_fbo(IWineD3DDeviceImpl *This, GLenum fbo_target, DWORD idx, IWineD3DSurface *surface) {
|
||||
const IWineD3DSurfaceImpl *surface_impl = (IWineD3DSurfaceImpl *)surface;
|
||||
GLenum texttarget, target;
|
||||
GLint old_binding;
|
||||
|
||||
texttarget = surface_impl->glDescription.target;
|
||||
target = texttarget == GL_TEXTURE_2D ? GL_TEXTURE_2D : GL_TEXTURE_CUBE_MAP_ARB;
|
||||
glGetIntegerv(texttarget == GL_TEXTURE_2D ? GL_TEXTURE_BINDING_2D : GL_TEXTURE_BINDING_CUBE_MAP_ARB, &old_binding);
|
||||
|
||||
IWineD3DSurface_PreLoad(surface);
|
||||
|
||||
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glBindTexture(target, old_binding);
|
||||
|
||||
GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_COLOR_ATTACHMENT0_EXT + idx, texttarget, surface_impl->glDescription.textureName, 0));
|
||||
|
||||
checkGLcall("attach_surface_fbo");
|
||||
}
|
||||
|
||||
static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurface *surface, CONST WINED3DRECT *rect, WINED3DCOLOR color) {
|
||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
|
||||
IWineD3DSwapChain *swapchain;
|
||||
|
||||
swapchain = get_swapchain(surface);
|
||||
if (swapchain) {
|
||||
GLenum buffer;
|
||||
|
||||
TRACE("Surface %p is onscreen\n", surface);
|
||||
|
||||
GL_EXTCALL(glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0));
|
||||
buffer = surface_get_gl_buffer(surface, swapchain);
|
||||
glDrawBuffer(buffer);
|
||||
checkGLcall("glDrawBuffer()");
|
||||
} else {
|
||||
TRACE("Surface %p is offscreen\n", surface);
|
||||
bind_fbo(iface, GL_DRAW_FRAMEBUFFER_EXT, &This->dst_fbo);
|
||||
attach_surface_fbo(This, GL_DRAW_FRAMEBUFFER_EXT, 0, surface);
|
||||
}
|
||||
|
||||
if (rect) {
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
if(!swapchain) {
|
||||
glScissor(rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1);
|
||||
} else {
|
||||
glScissor(rect->x1, ((IWineD3DSurfaceImpl *)surface)->currentDesc.Height - rect->y2,
|
||||
rect->x2 - rect->x1, rect->y2 - rect->y1);
|
||||
}
|
||||
checkGLcall("glScissor");
|
||||
} else {
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE));
|
||||
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORWRITEENABLE));
|
||||
|
||||
glClearColor(D3DCOLOR_R(color), D3DCOLOR_G(color), D3DCOLOR_B(color), D3DCOLOR_A(color));
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
checkGLcall("glClear");
|
||||
|
||||
if (This->render_offscreen) {
|
||||
bind_fbo(iface, GL_FRAMEBUFFER_EXT, &This->fbo);
|
||||
} else {
|
||||
GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
|
||||
checkGLcall("glBindFramebuffer()");
|
||||
}
|
||||
|
||||
if (swapchain && surface == ((IWineD3DSwapChainImpl *)swapchain)->frontBuffer
|
||||
&& ((IWineD3DSwapChainImpl *)swapchain)->backBuffer) {
|
||||
glDrawBuffer(GL_BACK);
|
||||
checkGLcall("glDrawBuffer()");
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DDeviceImpl_ColorFill(IWineD3DDevice *iface, IWineD3DSurface *pSurface, CONST WINED3DRECT* pRect, WINED3DCOLOR color) {
|
||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
|
||||
IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *) pSurface;
|
||||
@ -4985,11 +5084,16 @@ static HRESULT WINAPI IWineD3DDeviceImpl_ColorFill(IWineD3DDevice *iface, IWineD
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
}
|
||||
|
||||
/* Just forward this to the DirectDraw blitting engine */
|
||||
memset(&BltFx, 0, sizeof(BltFx));
|
||||
BltFx.dwSize = sizeof(BltFx);
|
||||
BltFx.u5.dwFillColor = color;
|
||||
return IWineD3DSurface_Blt(pSurface, (RECT *) pRect, NULL, NULL, WINEDDBLT_COLORFILL, &BltFx, WINED3DTEXF_NONE);
|
||||
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) {
|
||||
color_fill_fbo(iface, pSurface, pRect, color);
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
} else {
|
||||
/* Just forward this to the DirectDraw blitting engine */
|
||||
memset(&BltFx, 0, sizeof(BltFx));
|
||||
BltFx.dwSize = sizeof(BltFx);
|
||||
BltFx.u5.dwFillColor = color;
|
||||
return IWineD3DSurface_Blt(pSurface, (RECT *) pRect, NULL, NULL, WINEDDBLT_COLORFILL, &BltFx, WINED3DTEXF_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
/* rendertarget and deptth stencil functions */
|
||||
@ -5108,17 +5212,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetDepthStencilSurface(IWineD3DDevice
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
static void bind_fbo(IWineD3DDevice *iface, GLenum target, GLuint *fbo) {
|
||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
||||
|
||||
if (!*fbo) {
|
||||
GL_EXTCALL(glGenFramebuffersEXT(1, fbo));
|
||||
checkGLcall("glGenFramebuffersEXT()");
|
||||
}
|
||||
GL_EXTCALL(glBindFramebufferEXT(target, *fbo));
|
||||
checkGLcall("glBindFramebuffer()");
|
||||
}
|
||||
|
||||
/* TODO: Handle stencil attachments */
|
||||
static void set_depth_stencil_fbo(IWineD3DDevice *iface, IWineD3DSurface *depth_stencil) {
|
||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
||||
@ -5154,26 +5247,6 @@ static void set_depth_stencil_fbo(IWineD3DDevice *iface, IWineD3DSurface *depth_
|
||||
}
|
||||
}
|
||||
|
||||
static void attach_surface_fbo(IWineD3DDeviceImpl *This, GLenum fbo_target, DWORD idx, IWineD3DSurface *surface) {
|
||||
const IWineD3DSurfaceImpl *surface_impl = (IWineD3DSurfaceImpl *)surface;
|
||||
GLenum texttarget, target;
|
||||
GLint old_binding;
|
||||
|
||||
texttarget = surface_impl->glDescription.target;
|
||||
target = texttarget == GL_TEXTURE_2D ? GL_TEXTURE_2D : GL_TEXTURE_CUBE_MAP_ARB;
|
||||
glGetIntegerv(texttarget == GL_TEXTURE_2D ? GL_TEXTURE_BINDING_2D : GL_TEXTURE_BINDING_CUBE_MAP_ARB, &old_binding);
|
||||
|
||||
IWineD3DSurface_PreLoad(surface);
|
||||
|
||||
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glBindTexture(target, old_binding);
|
||||
|
||||
GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_COLOR_ATTACHMENT0_EXT + idx, texttarget, surface_impl->glDescription.textureName, 0));
|
||||
|
||||
checkGLcall("attach_surface_fbo");
|
||||
}
|
||||
|
||||
static void set_render_target_fbo(IWineD3DDevice *iface, DWORD idx, IWineD3DSurface *render_target) {
|
||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
||||
IWineD3DSurfaceImpl *rtimpl = (IWineD3DSurfaceImpl *)render_target;
|
||||
@ -5280,19 +5353,6 @@ void apply_fbo_state(IWineD3DDevice *iface) {
|
||||
check_fbo_status(iface);
|
||||
}
|
||||
|
||||
static IWineD3DSwapChain *get_swapchain(IWineD3DSurface *target) {
|
||||
HRESULT hr;
|
||||
IWineD3DSwapChain *swapchain;
|
||||
|
||||
hr = IWineD3DSurface_GetContainer(target, &IID_IWineD3DSwapChain, (void **)&swapchain);
|
||||
if (SUCCEEDED(hr)) {
|
||||
IWineD3DSwapChain_Release((IUnknown *)swapchain);
|
||||
return swapchain;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, const WINED3DRECT *src_rect,
|
||||
IWineD3DSurface *dst_surface, const WINED3DRECT *dst_rect, const WINED3DTEXTUREFILTERTYPE filter, BOOL flip) {
|
||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
||||
|
Loading…
Reference in New Issue
Block a user