Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

johnnyBravo

Texture Map with Lighting, stops my 3d objects from showing!

This topic is 5388 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

im using the tutorial Texture Map with Lighting from the dx9 sdk. when i call
quote:
lp_Device->SetVertexShader( m_pVertexShader );
it stops my 3d objects from showing. I don''t know if this is part of the setting up and more settings are needed or what. But when i run the rest of the code with it, i don''t see my 3d objects no more!. Heres all the code This code is being run in the render loop
// Identify the shader.

lp_Device->SetVertexShader( m_pVertexShader );
// Define the texture stage(s) and set the texture(s) used

lp_Device->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
lp_Device->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
lp_Device->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
lp_Device->SetTexture( 0, NULL );
this code is being run with the matrix code which is in a method called into the render loop
float constants[4] = {0, 0.5f, 1.0f, 2.0f};
lp_Device->SetVertexShaderConstantF( 0, (float*)&constants, 1 );

D3DXMATRIX mat;
D3DXMatrixMultiply( &mat, &matView, &matProj );
D3DXMatrixTranspose( &mat, &mat );
lp_Device->SetVertexShaderConstantF( 4, (float*)&mat, 4 );

float color[4] = {1,1,1,1};
lp_Device->SetVertexShaderConstantF( 8, (float*)&color, 1 );
some of the declarations which is above the code that is next
LPDIRECT3DVERTEXSHADER9 m_pVertexShader;
TCHAR        strShaderPath[512];
LPD3DXBUFFER pCode;                  // buffer with the assembled shader code

LPD3DXBUFFER pErrorMsgs;             // buffer with error messages


D3DVERTEXELEMENT9 decl[] = 	
{
{ 0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
{ 0, 12, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,   0 },
{ 0, 24, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,  0 },
{ 0, 28, D3DDECLTYPE_FLOAT2,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
D3DDECL_END()
};
the code that is init, which i run once
DXUtil_FindMediaFileCb( strShaderPath, sizeof(strShaderPath), _T("VertexShader.vsh") );
D3DXAssembleShaderFromFile( strShaderPath, NULL, NULL, 0, &pCode, &pErrorMsgs ); 
lp_Device->CreateVertexShader((DWORD*)pCode->GetBufferPointer(), &m_pVertexShader);
if (pCode != NULL)
	pCode->Release();
			
if (pErrorMsgs != NULL)
	pErrorMsgs->Release();
I can''t work out what the error is. If there is anything extra or clearing up , let me know, i can see that it is a little vague. But please have a quick look Thanks.

Share this post


Link to post
Share on other sites
Advertisement
maybe the objects are just rendered in black. try to clear the backbuffer with a colour, and see if you still don''t see anything. if you see anything, there is something wrong with your lighting or texture blending or so. and if you still don''t see a thing, you know it really isn''t rendered

My Site

Share this post


Link to post
Share on other sites
I think the reason you''re not seeing anything is because the transformation matrix you pass into your vertex shader only does View * Proj. I doubt that the vertices of all your objects are already in world space.

If you''re drawing multiple objects in a scene (which is probably the case unless you''re doing some kind of test program), then you should really have two matrices in your vertex shader. You need to pass the World transform matrix for each object as well as the concatenated View and Projection matrices for the scene (which I see from your code you''re already doing). Technically you could concatenate all three matrices into one matrix but often times you need the world position of a vertex for some other calculation.

In your vertex shader you have to transform the vertex coordinates into world space by multiplying them with the World matrix that you passed into the shader. Then you take this output and multiply it by your concatenated ViewProj matrix. This result then gets output to the position register in your vertex shader.

Hope this helps,
neneboricua

Share this post


Link to post
Share on other sites
hmmm ive got a world matrix function that i just call to set the object in the world.

So is this what you mean by the world matrix?

If so how would i times so many different world matrix to the vertex shader?

Share this post


Link to post
Share on other sites
quote:
Original post by johnnyBravo
hmmm ive got a world matrix function that i just call to set the object in the world.

So is this what you mean by the world matrix?

If so how would i times so many different world matrix to the vertex shader?

If you mean something like m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld ); then this is your problem. This function only works in the fixed function pipeline. Once you start using shaders, you have to do ALL transformations yourself.

To render multiple objects, you would do soemthing like this:
...
mat <-- World matrix for model1
SetVertexShaderConstantF( 0, (float*)&mat, 4 );
model1->Render();

mat <-- World matrix for model2
SetVertexShaderConstantF( 0, (float*)&mat, 4 );
model2->Render();
....

Each object in your world should have its own position (and thus its own world transformation matrix). So you pass each model's world matrix to your vertex shader and then render the model. Repeat this until you render all objects in your scene. You could use something like this

for( DWORD i = 0; i < NUM_OBJECTS; i++ )
{
SetVertexShaderConstantF( 0, (float*)&(models[i]->GetWorldMatrix()), 4 );
models[i]->Render();
}


Hope this helps,
neneboricua

[edited by - neneboricua19 on September 22, 2003 10:48:59 PM]

Share this post


Link to post
Share on other sites
This what i did:

void World(float x, float y, float z, float xa, float ya, float za,float xs, float ys, float zs)
{
// Identify the shader.

lp_Device->SetVertexShader( m_pVertexShader );
// Define the texture stage(s) and set the texture(s) used

lp_Device->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
lp_Device->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
lp_Device->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
lp_Device->SetTexture( 0, NULL );
D3DXMATRIXA16 matRot, matWorld,matScale;
//shader stuff

float constants[4] = {0, 0.5f, 1.0f, 2.0f};
lp_Device->SetVertexShaderConstantF( 0, (float*)&constants, 1 );

D3DXMatrixMultiply( &matWorld, &matView, &matProj );
D3DXMatrixTranspose( &matWorld, &matWorld );
lp_Device->SetVertexShaderConstantF( 4, (float*)&matWorld, 4 );

float color[4] = {1,1,1,0};
lp_Device->SetVertexShaderConstantF( 8, (float*)&color, 1 );

float lightDir[4] = {-1,0,1,0}; // fatter slice

lp_Device->SetVertexShaderConstantF( 12, (float*)&lightDir, 1 );


///original matrix code

D3DXMatrixTranslation(&matWorld , x ,y,z);
D3DXMatrixScaling(&matScale, xs, ys, zs);
D3DXMatrixMultiply(&matWorld,&matScale,&matWorld);
D3DXMatrixRotationYawPitchRoll(&matRot,ya,xa,za );
D3DXMatrixMultiply(&matWorld,&matRot,&matWorld);
lp_Device->SetTransform( D3DTS_WORLD, &matWorld);

}


There is one thing that i think could be the problem.

The shader file specifies to use diffuse vertex colours, where my vertices use:
normals
position
texturemap

this is their shader file

// v7 vertex diffuse color used for the light color

// v8 texture

// c4 view projection matrix

// c12 light direction


vs_1_1 // version instruction

dcl_position v0 // declare register data

dcl_normal v4 // v0 is position, v4 is normal

dcl_color0 v7 // v7 is diffuse color

dcl_texcoord0 v8 // v8 is texture coordinates

m4x4 oPos, v0, c4 // transform vertices using view projection transform

dp3 r0, v4, c12 // perform lighting N dot L calculation in world

mul oD0, r0.x , v7 // calculate final pixel color from light intensity and

// interpolated diffuse vertex color

mov oT0.xy , v8 // copy texture coordinates to output


im not sure how to modify this file for my circumstances.

What ive tried is removing the :
dcl_color0 v7 // v7 is diffuse color

but of this code here i dont know which one to remove:
edit from the shader file

mul oD0, r0.x , v7 // calculate final pixel color from light intensity and

// interpolated diffuse vertex color









and this is my current initilisation method, i know ive already posted this at the start but ive slightly modified it by putting everything together more.

D3DVERTEXELEMENT9 decl[] =
{
{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
{ 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },
{ 0, 24, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 },
{ 0, 28, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
D3DDECL_END()
};

DXUtil_FindMediaFileCb( strShaderPath, sizeof(strShaderPath), _T("VertexShader.vsh") );
D3DXAssembleShaderFromFile( strShaderPath, NULL, NULL, 0, &pCode, &pErrorMsgs );
lp_Device->CreateVertexShader((DWORD*)pCode->GetBufferPointer(), &m_pVertexShader);

if (pCode != NULL)
pCode->Release();

if (pErrorMsgs != NULL)
pErrorMsgs->Release();


and just the declartions

LPDIRECT3DVERTEXSHADER9 m_pVertexShader;
TCHAR strShaderPath[512];
LPD3DXBUFFER pCode; // buffer with the assembled shader code

LPD3DXBUFFER pErrorMsgs; // buffer with error messages




Share this post


Link to post
Share on other sites
This is your main problem
quote:
///original matrix code D3DXMatrixTranslation(&matWorld , x ,y,z); D3DXMatrixScaling(&matScale, xs, ys, zs); D3DXMatrixMultiply(&matWorld,&matScale,&matWorld); D3DXMatrixRotationYawPitchRoll(&matRot,ya,xa,za ); D3DXMatrixMultiply(&matWorld,&matRot,&matWorld); lp_Device->SetTransform( D3DTS_WORLD, &matWorld);

See that last line?? You can''t do that when you''re using shaders. You have to perform this transformation inside the vertex shader. Instead of calling SetTransform with this matrix, you have to transpose it and then set it as a constant in your vertex shader like you do the concatenated View and Projection matrices:
D3DXMatrixMultiply( &matWorld, &matView, &matProj );
D3DXMatrixTranspose( &matWorld, &matWorld );
lp_Device->SetVertexShaderConstantF( 4, (float*)&matWorld, 4 );

I''m going to guess that you''re calling your "void World(...)" function for every object you render. That''s fine since you''re just getting the hang of how everything works. If that''s the case, then try this:
void World(float x, float y, float z, float xa, float ya, float za,float xs, float ys, float zs)
{
// Identify the shader.

lp_Device->SetVertexShader( m_pVertexShader );
// Define the texture stage(s) and set the texture(s) used

lp_Device->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
lp_Device->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
lp_Device->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
lp_Device->SetTexture( 0, NULL );
D3DXMATRIXA16 matRot, matWorld,matScale;
//shader stuff

float constants[4] = {0, 0.5f, 1.0f, 2.0f};
lp_Device->SetVertexShaderConstantF( 0, (float*)&constants, 1 );

///original matrix code

D3DXMatrixTranslation(&matWorld , x ,y,z);
D3DXMatrixScaling(&matScale, xs, ys, zs);
D3DXMatrixMultiply(&matWorld,&matScale,&matWorld);
D3DXMatrixRotationYawPitchRoll(&matRot,ya,xa,za );
D3DXMatrixMultiply(&matWorld,&matRot,&matWorld);
D3DXMatrixMultiply(&matWorld,&matWorld,&matView);
D3DXMatrixMultiply( &matWorld, &matWorld, &matProj );
D3DXMatrixTranspose( &matWorld, &matWorld );
lp_Device->SetVertexShaderConstantF( 4, (float*)&matWorld, 4 );

float color[4] = {1,1,1,0};
lp_Device->SetVertexShaderConstantF( 8, (float*)&color, 1 );

float lightDir[4] = {-1,0,1,0}; // fatter slice

lp_Device->SetVertexShaderConstantF( 12, (float*)&lightDir, 1 );
}


As far as your vertex shader goes, it looks ok. But it was only made to hande geometry that isn''t moved around the scene by the world transform. You not only have to transform your vertex into world space but your normal as well. The fixed function pipeline does this for you, but when you start using shaders, you have to do it yourself. Try to do a search for "transforming normals" or something like that. In your particular case, if all your scalings are uniform (i.e. xs==ys==zs) then you can use the same matrix to transform your normals that you use to transform your vertices.

The vertex shader seems to match your vertex declaration so there shouldn''t be a problem there.

This should get you up and running, hopefully,
neneboricua

Share this post


Link to post
Share on other sites
still i see nothing.

Just a thing im curious of is the line
quote:

D3DXMatrixMultiply( &matWorld, &matWorld, &matProj );


Like is that supposed to be there, as its not in the dx help file tut etc.

this is the worldmatrix method again to the best of my knowledge it should work(its basically the same one you posted for me to use)

void World(float x, float y, float z, float xa, float ya, float za,float xs, float ys, float zs)
{
float constants[4] = {0, 0.5f, 1.0f, 2.0f};
lp_Device->SetVertexShaderConstantF( 0, (float*)&constants, 1 );

D3DXMATRIXA16 matView,matSpin, matProj;
D3DXMatrixLookAtLH( &matView, &D3DXVECTOR3( 30, -10, 50 ), &D3DXVECTOR3( 0, 0, 0 ), &D3DXVECTOR3( 0, 1, 0 ));
D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/2, 1.0f, 1, 500 );

D3DXMATRIXA16 matRot, matWorld,matScale;
D3DXMatrixTranslation(&matWorld , x ,y,z);
D3DXMatrixScaling(&matScale, xs, ys, zs);
D3DXMatrixMultiply(&matWorld,&matScale,&matWorld);
D3DXMatrixRotationYawPitchRoll(&matRot,ya,xa,za );
D3DXMatrixMultiply(&matWorld,&matRot,&matWorld);
D3DXMatrixMultiply( &matWorld, &matView, &matProj );
D3DXMatrixTranspose( &matWorld, &matWorld );



lp_Device->SetVertexShaderConstantF( 4, (float*)&matWorld, 4 );

float color[4] = {1,1,1,0};
lp_Device->SetVertexShaderConstantF( 8, (float*)&color, 1 );
float lightDir[4] = {-1,0,1,0}; // fatter slice

lp_Device->SetVertexShaderConstantF( 12, (float*)&lightDir, 1 );

}


and i put the renderstate code in the render loop...

g.Matrix.World(0,0,0, 0,0,0 , 1,1,1);
g.Light.Material(0,0.5,0,0,false);


g.lp_Device->SetVertexShader( g.Matrix.m_pVertexShader );
g.lp_Device->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
g.lp_Device->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
g.lp_Device->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
g.lp_Device->SetTexture( 0, g.Texture.lp_Texture[0] );

g.Vertice.Draw(D3DPT_TRIANGLELIST,0,1);


I really dont know where im going wrong, thanks so much for your patience

[edited by - johnnyBravo on September 24, 2003 2:27:56 AM]

Share this post


Link to post
Share on other sites
In your "World" function you have these two lines:

D3DXMatrixMultiply(&matWorld,&matRot,&matWorld);
D3DXMatrixMultiply( &matWorld, &matView, &matProj );

The first line sets it up so that "matWorld" has the matrix that you need to transform your geometry by. It has all of your rotations, scaling, movement already in it. But then on the second line, you overwrite this matrix by multiplying your View and Projection matrices and putting the result in "matWorld"! That''s why you don''t see anything. The code I originally posted for you should have worked. It should be this:

D3DXMatrixMultiply(&matWorld,&matRot,&matWorld);
D3DXMatrixMultiply(&matWorld,&matWorld,&matView);
D3DXMatrixMultiply( &matWorld, &matWorld, &matProj );

The first line here is the same as the first line above. But notice that the second line uses "matWorld" twice. The first parameter to this function is where you want the result written. The next two parameters are the two matrices that you want multiplied together. Our main goal is to have this result:
matWorld = matWorld * matView * matProj.

So the three lines above are basically doing this: matWorld = ((matWorld * matView) * matProj). We multiply the "world" matrix by the "view" matrix, store that result back in the "world" matrix and then multiply that result by the "proj"ection matrix. This gives us our final transformation matrix.

What I would suggest you do is try to render something without using any rotations, translations or scaling. Hard-code a triangle at a certain position in space and place the camera directly in front of the triangle. In this particular case, the matrix that you pass to your vertex shader will just be an the View * Proj matrix. No scaling, rotations, etc... You could use the DX9 App Wizard to create an app for you that draws a triangle right in fron of the camera. The wizard doesn''t use shaders but once it makes the sample app for you, you can replace the fixed function stuff (things like "SetTransform()") with your shaders.

The problems you''re having are really transformation problems. The thing is that when you write shaders, you have to really understand how transformations work. If you''re not clear on how it all works, then maybe you should practice a little more with the fixed function pipeline until you''re more comfortable with doing all the transformations yourself.

neneboricua

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!