DirectX9 Setting a meshs texture through the fx file

Started by
5 comments, last by TomKQT 12 years ago
I am having a problem setting a mesh's texure with the effect file instead of using device->SetTexure because i am using shaders, here is my shader code

shader.fx

float4x4 World;
float4x4 View;
float4x4 Projection;

texture gTex;

sampler TexS = sampler_state
{
Texture = ;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = LINEAR;
AddressU = WRAP;
AddressV = WRAP;
};

struct VertexOut
{
float4 Pos : POSITION;
float2 tex0 : TEXCOORD2;
};

VertexOut VShader(float4 Pos : POSITION,float2 tex0 : TEXCOORD0)
{
VertexOut Vert = (VertexOut)0;
float4x4 Transform;
Transform = mul(World, View);
Transform = mul(Transform, Projection);
Vert.Pos = mul(Pos, Transform);
Vert.tex0 = tex0;
return Vert;
}

float4 PS(float2 tex0 : TEXCOORD2) : COLOR
{
return tex2D(TexS, tex0);
}

technique FirstTechnique
{
pass FirstPass
{
Lighting = TRUE;
ZEnable = TRUE;
//FillMode = WireFrame;
VertexShader = compile vs_2_0 VShader();
PixelShader = compile ps_2_0 TransformPS();
}
}


//loading the texture and setting the effect params
D3DXCreateTextureFromFile(d3ddev,"wings.bmp",&Texture);
effect->FindNextValidTechnique(NULL, &technique); // find the best technique
xWorldHandle = effect->GetParameterByName(NULL,"World");
xViewHandle = effect->GetParameterByName(NULL,"View");
xProjectionHandle = effect->GetParameterByName(NULL,"Projection");
xTextureHandle = effect->GetParameterByName(NULL,"gTex");

//rendering the mesh with effect

effect->SetTexture(xTextureHandle,Texture);

//render with shader
effect->Begin(NULL, NULL); // begin using the effect
effect->BeginPass(0); // begin the pass
//draw here

for(DWORD i = 0; i < numMaterials; i++) // loop through each subset
{
meshSpaceship->DrawSubset(i); // draw the subset
}

effect->EndPass(); // end the pass
effect->End(); // end the effect


can anyone help me with this its driving me crazy
:)
Advertisement
[font=courier new,courier,monospace]Hi,[/font]

[font=courier new,courier,monospace]The standard way of applying texture through FX file is as follows : [/font]

[font=courier new,courier,monospace]- Load a texture in D3D using, D3DXCreateTextureFromFile ( say pObjectShader pointer[/font] )
[font=courier new,courier,monospace]- Use an Effect Pointer to call SetTexture function in D3D with "handle" parameter being texture name specified in the shader. [/font]
[font=courier new,courier,monospace]e.g> pEffect->SetTexture("gObjectShader", pObjectShader);[/font]
[font=courier new,courier,monospace]- Make sure you have sampler_state set correctly inside shader code with proper reference to the texture handle.[/font]
[font=courier new,courier,monospace]e.g>[/font]
[font=courier new,courier,monospace]sampler objSampler = sampler_state
{
Texture = <[/font][font=courier new,courier,monospace]gObjectShader[/font][font=courier new,courier,monospace]>;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = LINEAR;
AddressU = WRAP;
AddressV = WRAP;
};[/font]

[font=courier new,courier,monospace]- Final step, make sure inside you pixel shader you sample the texture using defined texture sampler ( e.g> tex2D([/font][font=courier new,courier,monospace]objSampler, In.Tex);) [/font]

[font=courier new,courier,monospace]Not sure if this will be helpful to you, Just giving you basic steps :) [/font]
First you need to assign the texture in the sampler definition:


float4x4 World;
float4x4 View;
float4x4 Projection;

texture gTex;

sampler TexS = sampler_state
{
Texture = <gTex>;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = LINEAR;
AddressU = WRAP;
AddressV = WRAP;
};



In your application code, you need to load the texture (D3DXCreateTextureFromFile) which will give you a pointer to the resource.
And finaly, in the rendering loop, you need to assign the corresponding texture to the shader every frame for every mesh subset that has a texture, using effect->SetTexture(xTextureHandle, ...);

As you can see, this is not something what the effect framework will do for you automatically, there's a lot of work left for you.

EDIT: Oh, I was too slow typing it, somebody else reacted in the meantime.
what if an .x file has 2 textures?
:)

what if an .x file has 2 textures?

As I said, there can be one texture per subset of the mesh, so you need to set the texture inside this loop:

for(DWORD i = 0; i < numMaterials; i++) // loop through each subset
{
effefct->SetTexture(xTextureHandle, meshTextures); //
meshSpaceship->DrawSubset(i); // draw the subset
}



Where meshTextures represents an array of texture resource pointers filled by you when you were loading the mesh.

Note that you cannot hard-type the texture name as in your first post:

D3DXCreateTextureFromFile(d3ddev,"wings.bmp",&Texture);

You have to take the texture name(s) from the x file.

It's good (in fact, it's quite necessary) to make your own simple "framework" for this (probably some classes/structures), because for each mesh (each x file) you need to store conveniently the mesh pointer together with pointers to the textures used by subsets of the mesh and also material definitions (diffuse color, specular power etc etc etc) of each subsets, when you'll implemenet lighting (the code you provided doesn't need this, yet).

And later you'll also find out that sometimes different meshes may use the same texture and it would be a waste to load the texture multiple times. So you'll implement some kind of "resource manager", that will automatically load a texture if you request it (by its filename) for the first time and give you a pointer to an existing one if you request it for the 2nd time.
what if i model my model in 3dsmax with more than 1 texture tho , thats what i a cant get my head around , how did you handle that in the pixel shaders return more than 1 texture etc..
:)
You mean multitexturing? Something like a single sphere with two textures applied on it, for example one diffuse texture and one bump-maping texture, or two textures combined into diffuse by a mask or something?
In this case you have a problem because the x file stores the name of only 1 texture per subset.

You can create the same effect in shaders as you had in 3ds max, but you'll have to store the name of the additional textures somewhere else.

This topic is closed to new replies.

Advertisement