Commit 81504d6a authored by Stefan Dösinger's avatar Stefan Dösinger Committed by Alexandre Julliard

wined3d: Support bump environment mapping using GL_NV_texture_shader.

parent 4a8b55d4
......@@ -367,6 +367,21 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
glEnable(GL_WEIGHT_SUM_UNITY_ARB);
checkGLcall("glEnable(GL_WEIGHT_SUM_UNITY_ARB)");
}
if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
int s;
glEnable(GL_TEXTURE_SHADER_NV);
checkGLcall("glEnable(GL_TEXTURE_SHADER_NV)");
/* Set up the previous texture input for all shader units. This applies to bump mapping, and in d3d
* the previous texture where to source the offset from is always unit - 1.
*/
for(s = 1; s < GL_LIMITS(textures); s++) {
GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + s));
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + s - 1);
checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, ...\n");
}
}
if(oldDrawable && oldCtx) {
glXMakeCurrent(display, oldDrawable, oldCtx);
......@@ -599,6 +614,11 @@ static inline void SetupForBlit(IWineD3DDeviceImpl *This, WineD3DContext *contex
glViewport(0, 0, width, height);
checkGLcall("glViewport");
Context_MarkStateDirty(context, STATE_VIEWPORT);
if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
glDisable(GL_TEXTURE_SHADER_NV);
checkGLcall("glDisable(GL_TEXTURE_SHADER_NV)");
}
}
/*****************************************************************************
......@@ -777,6 +797,10 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
case CTXUSAGE_DRAWPRIM:
/* This needs all dirty states applied */
if(context->last_was_blit && GL_SUPPORT(NV_TEXTURE_SHADER2)) {
glEnable(GL_TEXTURE_SHADER_NV);
checkGLcall("glEnable(GL_TEXTURE_SHADER_NV)");
}
for(i=0; i < context->numDirtyEntries; i++) {
dirtyState = context->dirtyArray[i];
idx = dirtyState >> 5;
......
......@@ -762,6 +762,8 @@ BOOL IWineD3DImpl_FillGLCaps(IWineD3D *iface, Display* display) {
} else if (strcmp(ThisExtn, "GL_NV_texture_shader2") == 0) {
TRACE_(d3d_caps)(" FOUND: NVIDIA (NV) Texture Shader (2) support\n");
gl_info->supported[NV_TEXTURE_SHADER2] = TRUE;
/* Prevent both extensions to be used at the same time. I don't expect them to play nice together */
gl_info->supported[ATI_ENVMAP_BUMPMAP] = FALSE;
} else if (strcmp(ThisExtn, "GL_NV_texture_shader3") == 0) {
TRACE_(d3d_caps)(" FOUND: NVIDIA (NV) Texture Shader (3) support\n");
gl_info->supported[NV_TEXTURE_SHADER3] = TRUE;
......@@ -803,7 +805,12 @@ BOOL IWineD3DImpl_FillGLCaps(IWineD3D *iface, Display* display) {
gl_info->supported[EXT_VERTEX_SHADER] = TRUE;
} else if (strcmp(ThisExtn, "GL_ATI_envmap_bumpmap") == 0) {
TRACE_(d3d_caps)(" FOUND: ATI Environment Bump Mapping support\n");
gl_info->supported[ATI_ENVMAP_BUMPMAP] = TRUE;
/* GL_ATI_envmap_bumpmap won't play nice with texture shaders, so disable it
* Won't occur in any real world situation though
*/
if(!gl_info->supported[NV_TEXTURE_SHADER2]) {
gl_info->supported[ATI_ENVMAP_BUMPMAP] = TRUE;
}
/**
* Apple
*/
......@@ -1680,6 +1687,17 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapt
return WINED3DERR_NOTAVAILABLE;
}
} else if(Usage & WINED3DUSAGE_QUERY_LEGACYBUMPMAP) {
if(GL_SUPPORT(NV_REGISTER_COMBINERS) && GL_SUPPORT(NV_TEXTURE_SHADER2)) {
switch (CheckFormat) {
case WINED3DFMT_V8U8:
TRACE_(d3d_caps)("[OK]\n");
return WINED3D_OK;
/* TODO: Other bump map formats */
default:
TRACE_(d3d_caps)("[FAILED]\n");
return WINED3DERR_NOTAVAILABLE;
}
}
if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
switch (CheckFormat) {
case WINED3DFMT_V8U8:
......@@ -1689,7 +1707,6 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapt
TRACE_(d3d_caps)("[FAILED]\n");
return WINED3DERR_NOTAVAILABLE;
}
/* TODO: GL_NV_TEXTURE_SHADER */
}
TRACE_(d3d_caps)("[FAILED]\n");
return WINED3DERR_NOTAVAILABLE;
......@@ -2225,8 +2242,14 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
*pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BUMPENVMAP;
} else if(GL_SUPPORT(NV_TEXTURE_SHADER)) {
/* TODO: environment bump mapping support with GL_NV_texture_shader */
} else if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
/* Bump mapping is supported already in NV_TEXTURE_SHADER, but that extension does
* not support 3D textures. This asks for trouble if an app uses both bump mapping
* and 3D textures. It also allows us to keep the code simpler by having texture
* shaders constantly enabled.
*/
*pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BUMPENVMAP;
/* TODO: Luminance bump map? */
}
#if 0
/* FIXME: Add
......
......@@ -866,7 +866,6 @@ void set_tex_op_nvrc(IWineD3DDevice *iface, BOOL is_alpha, int stage, WINED3DTEX
/* This is called by a state handler which has the gl lock held and a context for the thread */
switch(op)
{
case WINED3DTOP_DISABLE:
......@@ -1130,6 +1129,23 @@ void set_tex_op_nvrc(IWineD3DDevice *iface, BOOL is_alpha, int stage, WINED3DTEX
GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
break;
case WINED3DTOP_BUMPENVMAPLUMINANCE:
case WINED3DTOP_BUMPENVMAP:
if(GL_SUPPORT(NV_TEXTURE_SHADER)) {
/* The bump map stage itself isn't exciting, just read the texture. But tell the next stage to
* perform bump mapping and source from the current stage. Pretty much a SELECTARG2.
* ARG2 is passed through unmodified(apps will most likely use D3DTA_CURRENT for arg2, arg1
* (which will most likely be D3DTA_TEXTURE) is available as a texture shader input for the next stage
*/
GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
break;
}
default:
FIXME("Unhandled WINED3DTOP: stage %d, is_alpha %d, op %s (%#x), arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d\n",
stage, is_alpha, debug_d3dtop(op), op, arg1, arg2, arg3, texture_idx);
......@@ -1727,6 +1743,7 @@ void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP
}
case WINED3DTOP_BUMPENVMAPLUMINANCE:
FIXME("Implement bump environment mapping in GL_NV_texture_env_combine4 path\n");
default:
Handled = FALSE;
......@@ -2201,12 +2218,13 @@ void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP
checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
Handled = TRUE;
} else {
/* If GL_NV_TEXTURE_SHADER is supported insted the GL_NV_register_combiner path
* will be taken instead
} else if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
/* Technically texture shader support without register combiners is possible, but not expected to occur
* on real world cards, so for now a fixme should be enough
*/
Handled = FALSE;
FIXME("Implement bump mapping with GL_NV_texture_shader in non register combiner path\n");
}
Handled = FALSE;
break;
default:
Handled = FALSE;
......
......@@ -516,6 +516,7 @@ struct WineD3DContext {
BOOL lastWasPow2Texture[MAX_TEXTURES];
GLenum tracking_parm; /* Which source is tracking current colour */
BOOL last_was_blit, last_was_ckey;
char texShaderBumpMap;
/* The actual opengl context */
GLXContext glCtx;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment