Sign in to follow this  
colinolivant

Vertex Shader Texturing problem

Recommended Posts

colinolivant    128
Currently have a .x file, .jpg and a .fx file. I got these from toymaker and they include a flag mesh with a flag texture and a vertex shader that moves the flag. I've implemented these using directx and it displays on the screen with it moving in the wind. Good so far! My problem is that it doesn't display the texture. Its just black. I've spent ages on this, checking the vertex shader, checking that everything is passed ok. In the end I changed from D3DCREATE_MIXED_VERTEXPROCESSING to D3DCREATE_SOFTWARE_VERTEXPROCESSING and it turns the flag blue, but still doesn't put the texture on it. Anyone have any ideas on this it would be great!
// Fluttering flag vertex shader

// transformations provided by the app as input:
float4x4 matWorldViewProj: WORLDVIEWPROJECTION;
float time: TIME;

texture testTexture; // This texture will be loaded by the application

struct VS_OUTPUT
{
    float4 Pos : POSITION;
    float2 tex : TEXCOORD0;
};

VS_OUTPUT VS(float4 Pos : POSITION)
{
    VS_OUTPUT Out = (VS_OUTPUT)0; 

    float angle=(time%360)*2;

    Pos.z  = sin( Pos.x+angle);
    Pos.z += sin( Pos.y/2+angle);
    Pos.z *= Pos.x * 0.09f;

    // transform Position
    Out.Pos = mul( matWorldViewProj,Pos );
   
    // Just pass the texture co-ordinate as is
    Out.tex = tex; 

    return Out;
}

// Effect technique to be used
technique TVertexShaderOnly
{
    pass P0
    {
        Lighting = FALSE;
        
        // shaders
        VertexShader = compile vs_1_1 VS();
       
        // texture
        //Texture[1] = (testTexture);
       
        // sampler states
        MinFilter[0] = LINEAR;
        MagFilter[0] = LINEAR;
        MipFilter[0] = LINEAR;

        // set up texture stage states for single texture modulated by diffuse 
        ColorOp[0]   = MODULATE;
        ColorArg1[0] = TEXTURE;
        ColorArg2[0] = CURRENT;
        AlphaOp[0]   = DISABLE;

        ColorOp[1]   = DISABLE;
        AlphaOp[1]   = DISABLE;  
    }  
}

void setTechniqueVariables(D3DXMATRIX view,D3DXMATRIX matProj )
		{	
			
			D3DXMATRIX worldViewProjection = view * matProj;
			D3DXMatrixTranspose( &worldViewProjection, &worldViewProjection );

			g_pEffect->SetMatrix( "matWorldViewProj", &worldViewProjection );
			
			static float time = 0;
			time += 0.1f;
			g_pEffect->SetFloat( "time", time );

			D3DXMATRIX position ;
			g_pEffect->SetMatrix("Pos", &position );
			
			g_pEffect->SetTexture("testTexture", g_pTexture );
			g_pEffect->SetFloat("tex",1.0f);
		}

Share this post


Link to post
Share on other sites
You never set the texture as active in the pass. I've changed it to use a full sampler setup below.

Your texture stages are invalid. You cannot disable alphaops on a stage that has a colorop. Both must be present. I've also changed "CURRENT" to "DIFFUSE" to be more clear. CURRENT on stage 0 means DIFFUSE. CURRENT generally means the output from the previous stage, and there is no stage -1.

Try this:
sampler TextureSampler = sampler_state 
{
texture = <testTexture>;
AddressU = CLAMP;
AddressV = CLAMP;
AddressW = CLAMP;
MIPFILTER = LINEAR;
MINFILTER = LINEAR;
MAGFILTER = LINEAR;
};
and
    pass P0
{
Lighting = FALSE;

// shaders
VertexShader = compile vs_1_1 VS();

sampler[0] = <TextureSampler>; /* NEW */

// set up texture stage states for single texture modulated by diffuse
ColorOp[0] = MODULATE;
ColorArg1[0] = TEXTURE;
ColorArg2[0] = DIFFUSE; /* MODIFIED */
AlphaOp[0] = SELECTARG1; /* NEW */
AlphaArg1[0] = DIFFUSE; /* NEW */

ColorOp[1] = DISABLE;
AlphaOp[1] = DISABLE;
}

Share this post


Link to post
Share on other sites
colinolivant    128
Thanks for the tips most appreciated, I've added all the changes and i understand them but still no luck. In Software VERTEXPROCESSING mode it works but not in mixed or hardware.
Any other ideas? Thanks

Share this post


Link to post
Share on other sites
colinolivant    128
6800gts , Directx sdk june 2007, MS C++ 2005 pro
I have it working perfectly in software vetrexprocessing but none other. Do all shaders need to be in software mode? Is there any renderstate i need to do in hardware mode?
Source code:
http://www.colinolivant.co.uk/Directx HLSL flag.rar

Share this post


Link to post
Share on other sites
Software vertex processing will run the vertex shader in emulation on the CPU. This is useful if you want to use vertex shader features that a card doesn't support. Your card should support SM1, 2 and 3.

Knowing that your card should be fine, I took your posted FX file and put in FXComposer. It doesn't compile. You have a line "OUT.tex = tex;" but no input called tex.

I changed your input to be struct and update the code to use it. I got black output. Ah. Your texture stages are mixing in DIFFUSE or CURRENT, but your vertex shader never outputs it. When using shaders you must compute lighting yourself. Changing the COLOROP to SELECTARG1 reveals the texture. I'm not going to cover lighting in this post, as it's a lengthy topic that you should research a bit on your own first.

This one compiles, but has no lights:

// Fluttering flag vertex shader

// transformations provided by the app as input:
float4x4 matWorldViewProj: WORLDVIEWPROJECTION;
float time: TIME;

texture testTexture; // This texture will be loaded by the application
sampler TextureSampler = sampler_state
{
texture = <testTexture>;
AddressU = CLAMP;
AddressV = CLAMP;
AddressW = CLAMP;
MIPFILTER = LINEAR;
MINFILTER = LINEAR;
MAGFILTER = LINEAR;
};

struct VS_INPUT /* STRUCT IS NEW */
{ /* STRUCT IS NEW */
float4 Pos : POSITION; /* STRUCT IS NEW */
float2 tex : TEXCOORD0; /* STRUCT IS NEW */
}; /* STRUCT IS NEW */

struct VS_OUTPUT
{
float4 Pos : POSITION;
float2 tex : TEXCOORD0;
};

VS_OUTPUT VS(VS_INPUT IN) /* INPUT IS STRUCT */
{
VS_OUTPUT Out = (VS_OUTPUT)0;

float angle=(time%360)*2;

IN.Pos.z = sin( IN.Pos.x+angle); /* REFERS TO STRUCT */
IN.Pos.z += sin( IN.Pos.y/2+angle); /* REFERS TO STRUCT */
IN.Pos.z *= IN.Pos.x * 0.09f; /* REFERS TO STRUCT */

// transform Position
Out.Pos = mul( matWorldViewProj,IN.Pos ); /* REFERS TO STRUCT */

// Just pass the texture co-ordinate as is
Out.tex = IN.tex; /* REFERS TO STRUCT */

return Out;
}

// Effect technique to be used
technique TVertexShaderOnly
{
pass P0
{
Lighting = FALSE;

// shaders
VertexShader = compile vs_1_1 VS();

sampler[0] = <TextureSampler>; /* NEW */

// set up texture stage states for single texture modulated by diffuse
ColorOp[0] = SELECTARG1; /* NEWER THAN NEW */
ColorArg1[0] = TEXTURE;
ColorArg2[0] = DIFFUSE; /* MODIFIED */
AlphaOp[0] = SELECTARG1; /* NEW */
AlphaArg1[0] = DIFFUSE; /* NEW */

ColorOp[1] = DISABLE;
AlphaOp[1] = DISABLE;
}
}


Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this