From 3fd0916654906d2e4d0091322ea3162c18848cd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Tue, 27 Nov 2007 22:25:07 +0100 Subject: [PATCH] wined3d: Make the code aware of GL_ARB_texture_rectangle. --- dlls/wined3d/arb_program_shader.c | 11 ++++++- dlls/wined3d/baseshader.c | 4 +++ dlls/wined3d/basetexture.c | 26 +++++++++------ dlls/wined3d/device.c | 24 +++++++++++--- dlls/wined3d/glsl_shader.c | 54 +++++++++++++++++++++++-------- dlls/wined3d/pixelshader.c | 6 ++++ dlls/wined3d/state.c | 47 +++++++++++++++++++++++++-- dlls/wined3d/surface.c | 28 +++++++++++++++- dlls/wined3d/utils.c | 20 +++++++++--- 9 files changed, 182 insertions(+), 38 deletions(-) diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index a228f643b91..aad28653920 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -525,8 +525,17 @@ static void shader_hw_sample(SHADER_OPCODE_ARG* arg, DWORD sampler_idx, const ch break; case WINED3DSTT_2D: - tex_type = "2D"; + { + IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *) arg->shader; + IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device; + if(device->stateBlock->textures[sampler_idx] && + IWineD3DBaseTexture_GetTextureDimensions(device->stateBlock->textures[sampler_idx]) == GL_TEXTURE_RECTANGLE_ARB) { + tex_type = "RECT"; + } else { + tex_type = "2D"; + } break; + } case WINED3DSTT_VOLUME: tex_type = "3D"; diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c index 638db902f08..5f94a29cbd6 100644 --- a/dlls/wined3d/baseshader.c +++ b/dlls/wined3d/baseshader.c @@ -349,6 +349,10 @@ HRESULT shader_get_registers_used( } else { int texType = IWineD3DBaseTexture_GetTextureDimensions(stateBlock->textures[sampler_code]); switch(texType) { + /* We have to select between texture rectangles and 2D textures later because 2.0 and + * 3.0 shaders only have WINED3DSTT_2D as well + */ + case GL_TEXTURE_RECTANGLE_ARB: case GL_TEXTURE_2D: reg_maps->samplers[sampler_code] = (0x1 << 31) | WINED3DSTT_2D; break; diff --git a/dlls/wined3d/basetexture.c b/dlls/wined3d/basetexture.c index a1290f869ce..d17a4f477f1 100644 --- a/dlls/wined3d/basetexture.c +++ b/dlls/wined3d/basetexture.c @@ -285,11 +285,15 @@ HRESULT WINAPI IWineD3DBaseTextureImpl_BindTexture(IWineD3DBaseTexture *iface) { checkGLcall("glBindTexture"); if (isNewTexture) { /* For a new texture we have to set the textures levels after binding the texture. - * In theory this is all we should ever have to do, but because ATI's drivers are broken, we - * also need to set the texture dimensions before the texture is set */ - TRACE("Setting GL_TEXTURE_MAX_LEVEL to %d\n", This->baseTexture.levels - 1); - glTexParameteri(textureDimensions, GL_TEXTURE_MAX_LEVEL, This->baseTexture.levels - 1); - checkGLcall("glTexParameteri(textureDimensions, GL_TEXTURE_MAX_LEVEL, This->baseTexture.levels)"); + * In theory this is all we should ever have to do, but because ATI's drivers are broken, we + * also need to set the texture dimensions before the texture is set + * Beware that texture rectangles do not support mipmapping. + */ + if(textureDimensions != GL_TEXTURE_RECTANGLE_ARB) { + TRACE("Setting GL_TEXTURE_MAX_LEVEL to %d\n", This->baseTexture.levels - 1); + glTexParameteri(textureDimensions, GL_TEXTURE_MAX_LEVEL, This->baseTexture.levels - 1); + checkGLcall("glTexParameteri(textureDimensions, GL_TEXTURE_MAX_LEVEL, This->baseTexture.levels)"); + } if(textureDimensions==GL_TEXTURE_CUBE_MAP_ARB) { /* Cubemaps are always set to clamp, regardeless of the sampler state. */ glTexParameteri(textureDimensions, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); @@ -413,15 +417,17 @@ void WINAPI IWineD3DBaseTextureImpl_ApplyStateChanges(IWineD3DBaseTexture *iface TRACE("ValueMAG=%d setting MAGFILTER to %x\n", state, glValue); glTexParameteri(textureDimensions, GL_TEXTURE_MAG_FILTER, glValue); /* We need to reset the Aniotropic filtering state when we change the mag filter to WINED3DTEXF_ANISOTROPIC (this seems a bit weird, check the documentataion to see how it should be switched off. */ - if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC) && WINED3DTEXF_ANISOTROPIC == state) { + if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC) && WINED3DTEXF_ANISOTROPIC == state && + textureDimensions != GL_TEXTURE_RECTANGLE_ARB) { glTexParameteri(textureDimensions, GL_TEXTURE_MAX_ANISOTROPY_EXT, samplerStates[WINED3DSAMP_MAXANISOTROPY]); } This->baseTexture.states[WINED3DTEXSTA_MAGFILTER] = state; } - if(samplerStates[WINED3DSAMP_MINFILTER] != This->baseTexture.states[WINED3DTEXSTA_MINFILTER] || - samplerStates[WINED3DSAMP_MIPFILTER] != This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] || - samplerStates[WINED3DSAMP_MAXMIPLEVEL] != This->baseTexture.states[WINED3DTEXSTA_MAXMIPLEVEL]) { + if(textureDimensions != GL_TEXTURE_RECTANGLE_ARB && + (samplerStates[WINED3DSAMP_MINFILTER] != This->baseTexture.states[WINED3DTEXSTA_MINFILTER] || + samplerStates[WINED3DSAMP_MIPFILTER] != This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] || + samplerStates[WINED3DSAMP_MAXMIPLEVEL] != This->baseTexture.states[WINED3DTEXSTA_MAXMIPLEVEL])) { GLint glValue; This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] = samplerStates[WINED3DSAMP_MIPFILTER]; @@ -458,7 +464,7 @@ void WINAPI IWineD3DBaseTextureImpl_ApplyStateChanges(IWineD3DBaseTexture *iface } if(samplerStates[WINED3DSAMP_MAXANISOTROPY] != This->baseTexture.states[WINED3DTEXSTA_MAXANISOTROPY]) { - if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) { + if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC) && textureDimensions != GL_TEXTURE_RECTANGLE_ARB) { glTexParameteri(textureDimensions, GL_TEXTURE_MAX_ANISOTROPY_EXT, samplerStates[WINED3DSAMP_MAXANISOTROPY]); checkGLcall("glTexParameteri GL_TEXTURE_MAX_ANISOTROPY_EXT ..."); } else { diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 3ddbc77cc1a..d4d6e569acd 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -5739,8 +5739,16 @@ static void attach_surface_fbo(IWineD3DDeviceImpl *This, GLenum fbo_target, DWOR 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); + if(texttarget == GL_TEXTURE_2D) { + target = GL_TEXTURE_2D; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &old_binding); + } else if(texttarget == GL_TEXTURE_RECTANGLE_ARB) { + target = GL_TEXTURE_RECTANGLE_ARB; + glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_binding); + } else { + target = GL_TEXTURE_CUBE_MAP_ARB; + glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP_ARB, &old_binding); + } IWineD3DSurface_PreLoad(surface); @@ -6086,8 +6094,16 @@ static void set_depth_stencil_fbo(IWineD3DDevice *iface, IWineD3DSurface *depth_ GLint old_binding = 0; texttarget = depth_stencil_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); + if(texttarget == GL_TEXTURE_2D) { + target = GL_TEXTURE_2D; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &old_binding); + } else if(texttarget == GL_TEXTURE_RECTANGLE_ARB) { + target = GL_TEXTURE_RECTANGLE_ARB; + glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_binding); + } else { + target = GL_TEXTURE_CUBE_MAP_ARB; + glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP_ARB, &old_binding); + } IWineD3DSurface_PreLoad(depth_stencil); diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 1ba609fdd5c..dd18709b0a4 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -576,7 +576,12 @@ void shader_generate_glsl_declarations( shader_addline(buffer, "uniform sampler1D %csampler%u;\n", prefix, i); break; case WINED3DSTT_2D: - shader_addline(buffer, "uniform sampler2D %csampler%u;\n", prefix, i); + if(device->stateBlock->textures[i] && + IWineD3DBaseTexture_GetTextureDimensions(device->stateBlock->textures[i]) == GL_TEXTURE_RECTANGLE_ARB) { + shader_addline(buffer, "uniform sampler2DRect %csampler%u;\n", prefix, i); + } else { + shader_addline(buffer, "uniform sampler2D %csampler%u;\n", prefix, i); + } break; case WINED3DSTT_CUBE: shader_addline(buffer, "uniform samplerCube %csampler%u;\n", prefix, i); @@ -1081,7 +1086,7 @@ static inline const char* shader_get_comp_op( } } -static void shader_glsl_get_sample_function(DWORD sampler_type, BOOL projected, glsl_sample_function_t *sample_function) { +static void shader_glsl_get_sample_function(DWORD sampler_type, BOOL projected, BOOL texrect, glsl_sample_function_t *sample_function) { /* Note that there's no such thing as a projected cube texture. */ switch(sampler_type) { case WINED3DSTT_1D: @@ -1089,7 +1094,11 @@ static void shader_glsl_get_sample_function(DWORD sampler_type, BOOL projected, sample_function->coord_mask = WINED3DSP_WRITEMASK_0; break; case WINED3DSTT_2D: - sample_function->name = projected ? "texture2DProj" : "texture2D"; + if(texrect) { + sample_function->name = projected ? "texture2DRectProj" : "texture2DRect"; + } else { + sample_function->name = projected ? "texture2DProj" : "texture2D"; + } sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1; break; case WINED3DSTT_CUBE: @@ -2036,7 +2045,7 @@ void pshader_glsl_tex(SHADER_OPCODE_ARG* arg) { glsl_sample_function_t sample_function; DWORD sampler_type; DWORD sampler_idx; - BOOL projected; + BOOL projected, texrect = FALSE; DWORD mask = 0; /* All versions have a destination register */ @@ -2086,8 +2095,13 @@ void pshader_glsl_tex(SHADER_OPCODE_ARG* arg) { } } + if(deviceImpl->stateBlock->textures[sampler_idx] && + IWineD3DBaseTexture_GetTextureDimensions(deviceImpl->stateBlock->textures[sampler_idx]) == GL_TEXTURE_RECTANGLE_ARB) { + texrect = TRUE; + } + sampler_type = arg->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK; - shader_glsl_get_sample_function(sampler_type, projected, &sample_function); + shader_glsl_get_sample_function(sampler_type, projected, texrect, &sample_function); mask |= sample_function.coord_mask; if (hex_version < WINED3DPS_VERSION(2,0)) { @@ -2122,19 +2136,24 @@ void pshader_glsl_tex(SHADER_OPCODE_ARG* arg) { void shader_glsl_texldl(SHADER_OPCODE_ARG* arg) { IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*)arg->shader; + IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device; glsl_sample_function_t sample_function; glsl_src_param_t coord_param, lod_param; char dst_swizzle[6]; DWORD sampler_type; DWORD sampler_idx; + BOOL texrect = FALSE; shader_glsl_append_dst(arg->buffer, arg); shader_glsl_get_swizzle(arg->src[1], FALSE, arg->dst, dst_swizzle); sampler_idx = arg->src[1] & WINED3DSP_REGNUM_MASK; sampler_type = arg->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK; - shader_glsl_get_sample_function(sampler_type, FALSE, &sample_function); - shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], sample_function.coord_mask, &coord_param); + if(deviceImpl->stateBlock->textures[sampler_idx] && + IWineD3DBaseTexture_GetTextureDimensions(deviceImpl->stateBlock->textures[sampler_idx]) == GL_TEXTURE_RECTANGLE_ARB) { + texrect = TRUE; + } + shader_glsl_get_sample_function(sampler_type, FALSE, texrect, &sample_function); shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], sample_function.coord_mask, &coord_param); shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], WINED3DSP_WRITEMASK_3, &lod_param); @@ -2216,9 +2235,11 @@ void pshader_glsl_texdp3tex(SHADER_OPCODE_ARG* arg) { shader_glsl_get_write_mask(arg->dst, dst_mask); /* Do I have to take care about the projected bit? I don't think so, since the dp3 returns only one - * scalar, and projected sampling would require 4 + * scalar, and projected sampling would require 4. + * + * It is a dependent read - not valid with conditional NP2 textures */ - shader_glsl_get_sample_function(sampler_type, FALSE, &sample_function); + shader_glsl_get_sample_function(sampler_type, FALSE, FALSE, &sample_function); switch(count_bits(sample_function.coord_mask)) { case 1: @@ -2354,7 +2375,8 @@ void pshader_glsl_texm3x3tex(SHADER_OPCODE_ARG* arg) { shader_glsl_append_dst(arg->buffer, arg); shader_glsl_get_write_mask(arg->dst, dst_mask); - shader_glsl_get_sample_function(sampler_type, FALSE, &sample_function); + /* Dependent read, not valid with conditional NP2 */ + shader_glsl_get_sample_function(sampler_type, FALSE, FALSE, &sample_function); /* Sample the texture using the calculated coordinates */ shader_addline(arg->buffer, "%s(Psampler%u, tmp0.xyz)%s);\n", sample_function.name, reg, dst_mask); @@ -2406,7 +2428,8 @@ void pshader_glsl_texm3x3spec(SHADER_OPCODE_ARG* arg) { shader_glsl_append_dst(buffer, arg); shader_glsl_get_write_mask(arg->dst, dst_mask); - shader_glsl_get_sample_function(stype, FALSE, &sample_function); + /* Dependent read, not valid with conditional NP2 */ + shader_glsl_get_sample_function(stype, FALSE, FALSE, &sample_function); /* Sample the texture */ shader_addline(buffer, "%s(Psampler%u, tmp0.xyz)%s);\n", sample_function.name, reg, dst_mask); @@ -2440,7 +2463,8 @@ void pshader_glsl_texm3x3vspec(SHADER_OPCODE_ARG* arg) { shader_glsl_append_dst(buffer, arg); shader_glsl_get_write_mask(arg->dst, dst_mask); - shader_glsl_get_sample_function(sampler_type, FALSE, &sample_function); + /* Dependent read, not valid with conditional NP2 */ + shader_glsl_get_sample_function(sampler_type, FALSE, FALSE, &sample_function); /* Sample the texture using the calculated coordinates */ shader_addline(buffer, "%s(Psampler%u, tmp0.xyz)%s);\n", sample_function.name, reg, dst_mask); @@ -2468,7 +2492,8 @@ void pshader_glsl_texbem(SHADER_OPCODE_ARG* arg) { flags = deviceImpl->stateBlock->textureState[sampler_idx][WINED3DTSS_TEXTURETRANSFORMFLAGS]; sampler_type = arg->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK; - shader_glsl_get_sample_function(sampler_type, FALSE, &sample_function); + /* Dependent read, not valid with conditional NP2 */ + shader_glsl_get_sample_function(sampler_type, FALSE, FALSE, &sample_function); mask = sample_function.coord_mask; shader_glsl_get_write_mask(arg->dst, dst_swizzle); @@ -2557,7 +2582,8 @@ void pshader_glsl_texreg2rgb(SHADER_OPCODE_ARG* arg) { shader_glsl_append_dst(arg->buffer, arg); shader_glsl_get_write_mask(arg->dst, dst_mask); - shader_glsl_get_sample_function(sampler_type, FALSE, &sample_function); + /* Dependent read, not valid with conditional NP2 */ + shader_glsl_get_sample_function(sampler_type, FALSE, FALSE, &sample_function); shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], sample_function.coord_mask, &src0_param); shader_addline(arg->buffer, "%s(Psampler%u, %s)%s);\n", sample_function.name, sampler_idx, src0_param.param_str, dst_mask); diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c index c49f5145fa5..7981501f786 100644 --- a/dlls/wined3d/pixelshader.c +++ b/dlls/wined3d/pixelshader.c @@ -312,6 +312,12 @@ static inline VOID IWineD3DPixelShaderImpl_GenerateShader( if (GL_SUPPORT(ARB_DRAW_BUFFERS)) { shader_addline(&buffer, "#extension GL_ARB_draw_buffers : enable\n"); } + if (GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) { + /* The spec says that it doesn't have to be explicitly enabled, but the nvidia + * drivers write a warning if we don't do so + */ + shader_addline(&buffer, "#extension GL_ARB_texture_rectangle : enable\n"); + } /* Base Declarations */ shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, reg_maps, &buffer, &GLINFO_LOCATION); diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 1e61e1a9e97..787f3ead71b 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -354,7 +354,9 @@ static void state_alpha(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D * used WINED3DRS_COLORKEYENABLE state(which is d3d <= 3 only). The texture function will call alpha * in case it finds some texture+colorkeyenable combination which needs extra care. */ - if(stateblock->textures[0] && stateblock->textureDimensions[0] == GL_TEXTURE_2D) { + if(stateblock->textures[0] && ( + stateblock->textureDimensions[0] == GL_TEXTURE_2D || + stateblock->textureDimensions[0] == GL_TEXTURE_RECTANGLE_ARB)) { surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *)stateblock->textures[0])->surfaces[0]; if(surf->CKeyFlags & WINEDDSD_CKSRCBLT) { @@ -1696,10 +1698,31 @@ static void activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, glDisable(GL_TEXTURE_CUBE_MAP_ARB); checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)"); } + if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) { + glDisable(GL_TEXTURE_RECTANGLE_ARB); + checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)"); + } glEnable(GL_TEXTURE_2D); checkGLcall("glEnable(GL_TEXTURE_2D)"); } break; + case GL_TEXTURE_RECTANGLE_ARB: + if(GL_SUPPORT(NV_TEXTURE_SHADER2)) { + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, bumpmap ? GL_OFFSET_TEXTURE_2D_NV : GL_TEXTURE_RECTANGLE_ARB); + checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, ...)"); + } else { + glDisable(GL_TEXTURE_2D); + checkGLcall("glDisable(GL_TEXTURE_2D)"); + glDisable(GL_TEXTURE_3D); + checkGLcall("glDisable(GL_TEXTURE_3D)"); + if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) { + glDisable(GL_TEXTURE_CUBE_MAP_ARB); + checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)"); + } + glEnable(GL_TEXTURE_RECTANGLE_ARB); + checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)"); + } + break; case GL_TEXTURE_3D: if(GL_SUPPORT(NV_TEXTURE_SHADER2)) { glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_3D); @@ -1709,6 +1732,10 @@ static void activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, glDisable(GL_TEXTURE_CUBE_MAP_ARB); checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)"); } + if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) { + glDisable(GL_TEXTURE_RECTANGLE_ARB); + checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)"); + } glDisable(GL_TEXTURE_2D); checkGLcall("glDisable(GL_TEXTURE_2D)"); glEnable(GL_TEXTURE_3D); @@ -1724,6 +1751,10 @@ static void activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, checkGLcall("glDisable(GL_TEXTURE_2D)"); glDisable(GL_TEXTURE_3D); checkGLcall("glDisable(GL_TEXTURE_3D)"); + if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) { + glDisable(GL_TEXTURE_RECTANGLE_ARB); + checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)"); + } glEnable(GL_TEXTURE_CUBE_MAP_ARB); checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)"); } @@ -1742,6 +1773,10 @@ static void activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, glDisable(GL_TEXTURE_CUBE_MAP_ARB); checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)"); } + if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) { + glDisable(GL_TEXTURE_RECTANGLE_ARB); + checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)"); + } /* Binding textures is done by samplers. A dummy texture will be bound */ } } @@ -1796,6 +1831,10 @@ static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D glDisable(GL_TEXTURE_CUBE_MAP_ARB); checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)"); } + if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) { + glDisable(GL_TEXTURE_RECTANGLE_ARB); + checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)"); + } if(GL_SUPPORT(NV_TEXTURE_SHADER2) && mapped_stage < GL_LIMITS(textures)) { glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_NONE); } @@ -1873,7 +1912,8 @@ static void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D arg0 = stateblock->textureState[stage][WINED3DTSS_ALPHAARG0]; if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && stage == 0 && - stateblock->textures[0] && stateblock->textureDimensions[0] == GL_TEXTURE_2D) { + stateblock->textures[0] && + (stateblock->textureDimensions[0] == GL_TEXTURE_2D || stateblock->textureDimensions[0] == GL_TEXTURE_RECTANGLE_ARB)) { IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0]; if(surf->CKeyFlags & WINEDDSD_CKSRCBLT && @@ -2302,7 +2342,8 @@ static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCont * scaling is reapplied or removed, the texture matrix has to be reapplied */ if(!GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO) && sampler < MAX_TEXTURES) { - if(stateblock->textureDimensions[sampler] == GL_TEXTURE_2D) { + if(stateblock->textureDimensions[sampler] == GL_TEXTURE_2D || + stateblock->textureDimensions[sampler] == GL_TEXTURE_RECTANGLE_ARB) { if(((IWineD3DTextureImpl *) stateblock->textures[sampler])->baseTexture.pow2Matrix[0] != 1.0 || ((IWineD3DTextureImpl *) stateblock->textures[sampler])->baseTexture.pow2Matrix[5] != 1.0 ) { texIsPow2 = TRUE; diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 73ea660c519..89f8e9308da 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -3573,7 +3573,33 @@ static inline void surface_blt_to_drawable(IWineD3DSurfaceImpl *This, const RECT ActivateContext(device, device->render_targets[0], CTXUSAGE_BLIT); ENTER_GL(); - if(This->glDescription.target == GL_TEXTURE_2D) { + if(This->glDescription.target == GL_TEXTURE_RECTANGLE_ARB) { + glEnable(GL_TEXTURE_RECTANGLE_ARB); + checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)"); + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, This->glDescription.textureName); + checkGLcall("GL_TEXTURE_RECTANGLE_ARB, This->glDescription.textureName)"); + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + checkGLcall("glTexParameteri"); + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + checkGLcall("glTexParameteri"); + + coords[0].x = rect.left; + coords[0].z = 0; + + coords[1].x = rect.left; + coords[1].z = 0; + + coords[2].x = rect.right; + coords[2].z = 0; + + coords[3].x = rect.right; + coords[3].z = 0; + + coords[0].y = rect.top; + coords[1].y = rect.bottom; + coords[2].y = rect.bottom; + coords[3].y = rect.top; + } else if(This->glDescription.target == GL_TEXTURE_2D) { glEnable(GL_TEXTURE_2D); checkGLcall("glEnable(GL_TEXTURE_2D)"); glBindTexture(GL_TEXTURE_2D, This->glDescription.textureName); diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 2684225791f..15b37eac160 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -2797,10 +2797,17 @@ BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4] /* No oversized texture? This is easy */ if(!(This->Flags & SFLAG_OVERSIZE)) { /* Which rect from the texture do I need? */ - glTexCoord[0] = (float) Rect->left / (float) This->pow2Width; - glTexCoord[2] = (float) Rect->top / (float) This->pow2Height; - glTexCoord[1] = (float) Rect->right / (float) This->pow2Width; - glTexCoord[3] = (float) Rect->bottom / (float) This->pow2Height; + if(This->glDescription.target == GL_TEXTURE_RECTANGLE_ARB) { + glTexCoord[0] = (float) Rect->left; + glTexCoord[2] = (float) Rect->top; + glTexCoord[1] = (float) Rect->right; + glTexCoord[3] = (float) Rect->bottom; + } else { + glTexCoord[0] = (float) Rect->left / (float) This->pow2Width; + glTexCoord[2] = (float) Rect->top / (float) This->pow2Height; + glTexCoord[1] = (float) Rect->right / (float) This->pow2Width; + glTexCoord[3] = (float) Rect->bottom / (float) This->pow2Height; + } return TRUE; } else { @@ -2877,7 +2884,10 @@ BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4] Rect->bottom -= This->glRect.top; /* Get the gl coordinates. The gl rectangle is a power of 2, eigher the max size, - * or the pow2Width / pow2Height of the surface + * or the pow2Width / pow2Height of the surface. + * + * Can never be GL_TEXTURE_RECTANGLE_ARB because oversized surfaces are always set up + * as regular GL_TEXTURE_2D. */ glTexCoord[0] = (float) Rect->left / (float) (This->glRect.right - This->glRect.left); glTexCoord[2] = (float) Rect->top / (float) (This->glRect.bottom - This->glRect.top);