Jump to content
  • Advertisement
Sign in to follow this  
calidev234

Rendering Question.

This topic is 4831 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

I have an .x file that I made and when I look at it in the MeshViewer (that comes in the utility folder of the DirectX SDK) the rendering looks great: But when I use my render code it looks like shit:

Share this post


Link to post
Share on other sites
Advertisement
Hell, I meant to hit 'show preview' and hit submit....

Anyway, I'm using this to render the mesh:


//draw each mesh subset
for( DWORD i=0; i<model->material_count; i++ )
{
d3ddev->SetMaterial( &model->materials ); // Set the material and texture for this subset
d3ddev->SetTexture( 0, model->textures );
model->mesh->DrawSubset( i ); // Draw the mesh subset
}



And I'm setting up my render state like this:


//use ambient lighting and z-buffering
d3ddev->SetRenderState(D3DRS_ZENABLE, TRUE);
d3ddev->SetRenderState(D3DRS_LIGHTING, TRUE); //remember to fix this in ch11
d3ddev->SetRenderState(D3DRS_AMBIENT, WHITE); //should be ambient option instead
d3ddev->SetRenderState(D3DRS_VERTEXBLEND, 0);
d3ddev->SetRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
d3ddev->SetRenderState( D3DRS_SPECULARENABLE, TRUE );
d3ddev->SetNPatchMode( 0 );

//ADDED
d3ddev->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
d3ddev->SetRenderState( D3DRS_DITHERENABLE, TRUE );
d3ddev->SetRenderState( D3DRS_NORMALIZENORMALS, TRUE );
d3ddev->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
d3ddev->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
d3ddev->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID); //D3DFILL_WIREFRAME : D3DFILL_SOLID



And I'm setting up my lighting like this (in the Main Loop):


//Setup the Light
D3DLIGHT9 light;
D3DXVECTOR3 vecLightDirUnnormalized(1.0f, -1.0f, 1.0f);
ZeroMemory( &light, sizeof(D3DLIGHT9) );
light.Type = D3DLIGHT_SPOT; //D3DLIGHT_SPOT, D3DLIGHT_POINT, D3DLIGHT_FORCE_DWORD, D3DLIGHT_DIRECTIONAL
light.Diffuse.r = 0.5;
light.Diffuse.g = 0.5;
light.Diffuse.b = 0.5;
light.Specular.r = 0;
light.Specular.g = 0;
light.Specular.b = 0;

light.Ambient.r = 1;
light.Ambient.g = 1;
light.Ambient.b = 1;

D3DXVec3Normalize( (D3DXVECTOR3*)&light.Direction, &vecLightDirUnnormalized );

light.Position = D3DXVECTOR3(CAMERA_X, CAMERA_Y, CAMERA_Z);
light.Direction = D3DXVECTOR3( 0.0f, 0.0f, 1.0f);

light.Attenuation0 = 0.0f;
light.Attenuation1 = 0.0f;
light.Attenuation2 = 0.0f;

light.Range = ((float)sqrt(FLT_MAX));

switch( light.Type )
{
case D3DLIGHT_POINT:
light.Attenuation0 = 1.0f;
break;
case D3DLIGHT_DIRECTIONAL:
light.Position = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
break;
case D3DLIGHT_SPOT:
light.Position = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
light.Range = 1.0f;
light.Falloff = 100.0f;
light.Theta = 0.3f;
light.Phi = 0.40f;
light.Attenuation2 = 1.0f;
}

// Set Light for vertex shader
D3DXVECTOR4 vLightDir( 0.0f, 1.0f, -1.0f, 0.0f );
D3DXVec4Normalize( &vLightDir, &vLightDir );
d3ddev->SetVertexShaderConstantF(1, (float*)&vLightDir, 1);

d3ddev->SetLight(0, &light ) ;
d3ddev->LightEnable(1, TRUE );




So I'm not sure. Does anybody have any ideas.

Thank you,

Joshua

Share this post


Link to post
Share on other sites
From the looks of it, the only thing thats different is the lighting (consequently the shading).

I spotted this line:
d3ddev->SetRenderState(D3DRS_AMBIENT, WHITE);

Presuming that WHITE is actually the colour white - RGB(255,255,255) (or 1.0,1.0,1.0 [smile]) then it'll effectively "override" all of the lighting properties you've set.

D3DRS_AMBIENT is added to the final colour of all vertices, and WHITE being the maximum means that no matter what you do (short of adding a "dark light") it'll always stay at the maximum.

Change it to something more grey/black and you might get better results.

hth
Jack

Share this post


Link to post
Share on other sites
Hello Jack, thank you for your response. I changed what you suggested and the colors look fine now, however I'm still running into the rendering issue.

As can be seen by looking at the second image the wall closest to the camera view it should be a solid looing wall with three windows in it (refer to the first image for how it should look). However where the windows are rendered and certain pieces of the wall are not being rendered entirely. And if I rotate it will change. I'm certain the mesh file is made correctly; because I have culling turned on and it's fine; so I'm not really sure.

So I'm not certain.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
jollyjeffers hit the target. Play with the ambient and diffuse parameters and adjust the result as you would like.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by calidev234
Hello Jack, thank you for your response. I changed what you suggested and the colors look fine now, however I'm still running into the rendering issue.

As can be seen by looking at the second image the wall closest to the camera view it should be a solid looing wall with three windows in it (refer to the first image for how it should look). However where the windows are rendered and certain pieces of the wall are not being rendered entirely. And if I rotate it will change. I'm certain the mesh file is made correctly; because I have culling turned on and it's fine; so I'm not really sure.

So I'm not certain.


Oh.. sorry, I didn't pay attention. It seems a depth-buffer problem. Increase the z value of the near view-plane in D3DXMatrixPerspectiveLH/RH function.

Share this post


Link to post
Share on other sites
Ok, so I've been playing around with D3DXMatrixPerspectiveFovLH, as well as the Direct3D presentation parameters and I'm still not getting very good rendering.

The code is set up as follows:

1. Direct3D Presentation Parameters


D3DDISPLAYMODE dm;
d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &dm);
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));

d3dpp.BackBufferWidth = width;
d3dpp.BackBufferHeight = height;
d3dpp.BackBufferFormat = D3DFMT_R5G6B5;
d3dpp.BackBufferCount = 2;
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
d3dpp.MultiSampleQuality = 0;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = hwnd;
d3dpp.Windowed = true;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
d3dpp.Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;
d3dpp.FullScreen_RefreshRateInHz = 0;

//create Direct3D device
d3d->CreateDevice(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hwnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,
&d3ddev);



2. The Perspective

RECT r;
GetClientRect( hwnd, &r );
r.top += 28;
r.bottom -= 20;
float fAspect = (float)(r.right - r.left) / (float)(r.bottom - r.top);
D3DXMATRIX mat;
D3DXMatrixPerspectiveFovLH(&mat, 0.25f*3.141592654f, fAspect, 1.0f, 10000.0f);
d3ddev->SetTransform( D3DTS_PROJECTION, (D3DMATRIX*)&mat );





3. 3D Device setup


d3ddev->SetRenderState(D3DRS_ZENABLE, TRUE);
d3ddev->SetRenderState(D3DRS_LIGHTING, TRUE);
d3ddev->SetRenderState(D3DRS_AMBIENT, GREY);
d3ddev->SetRenderState(D3DRS_VERTEXBLEND, 0);
d3ddev->SetRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
d3ddev->SetRenderState( D3DRS_SPECULARENABLE, TRUE );
d3ddev->SetNPatchMode( 0 );

d3ddev->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
d3ddev->SetRenderState( D3DRS_DITHERENABLE, TRUE );
d3ddev->SetRenderState( D3DRS_NORMALIZENORMALS, FALSE );
d3ddev->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
d3ddev->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
d3ddev->SetRenderState( D3DRS_FILLMODE, D3DFILL_WIREFRAME);



4. The Light setup in the MainLoop


D3DLIGHT9 light;
D3DXVECTOR3 vecLightDirUnnormalized(1.0f, -1.0f, 1.0f);
ZeroMemory( &light, sizeof(D3DLIGHT9) );
light.Type = D3DLIGHT_POINT;
light.Diffuse.r = 1.0;
light.Diffuse.g = 1.0;
light.Diffuse.b = 1.0;
light.Ambient.r = 0.1f;
light.Ambient.g = 0.1f;
light.Ambient.b = 0.1f;

D3DXVec3Normalize( (D3DXVECTOR3*)&light.Direction, &vecLightDirUnnormalized );

light.Position = D3DXVECTOR3(PosX, PosY, PosZ);
light.Direction = D3DXVECTOR3( LookX, LookY, LookZ);

light.Range = ((float)sqrt(FLT_MAX));

switch( light.Type )
{
case D3DLIGHT_POINT:
light.Attenuation0 = 1.0f;
light.Range = 600.0f;
light.Falloff = .10f;
light.Theta = .1f;
light.Phi = .6f;
break;
case D3DLIGHT_DIRECTIONAL:
light.Position = D3DXVECTOR3(PosX, PosY, PosZ);
break;
case D3DLIGHT_SPOT:
light.Position = D3DXVECTOR3(PosX, PosY, PosZ);
light.Range = 1.0f;
light.Falloff = 1000.0f;
light.Theta = 0.3f;
light.Phi = 0.40f;
light.Attenuation2 = 1.0f;
}

// Set Light for vertex shader
D3DXVECTOR4 vLightDir( 0.0f, 1.0f, -1.0f, 0.0f );
D3DXVec4Normalize( &vLightDir, &vLightDir );
d3ddev->SetVertexShaderConstantF(1, (float*)&vLightDir, 1);

d3ddev->SetLight(0, &light ) ;
d3ddev->LightEnable(0, TRUE );



And all of this has this affect on the rendering:



As can be seen by the areas circled in red the rendering is not great. If I get really close to the walls then they look ok; but so far the rendering is not usable.

I'm a little lost. Does anybody have any ideas?

Thank you,

Joshua

Share this post


Link to post
Share on other sites
D3DXMATRIX mat;
D3DXMatrixPerspectiveFovLH(&mat, 0.25f*3.141592654f, fAspect, 1.0f, 10000.0f);
d3ddev->SetTransform( D3DTS_PROJECTION, (D3DMATRIX*)&mat );


10,000.0f still seems a little high to me. Which leads onto the next big question:

How big is that model we're looking at? Both as a raw model (the geometry you're loading from disk) and the rendered size (factoring in any scaling in the world matrix).

In knowing how big it is, you can do two things:

1. Maximize your depth value usage by, ideally, configuring zNear and zFar to exactly enclose the space that the model occupies. In reality this can be a bit of a bugger when the camera moves and the mesh rotates, but you can probably gain a lot by reducing the current zNear value.

2. As you observed, the D3D Mesh Viewer tool doesn't corrupt, so the actual raw data is probably fine (it's not stored in a form that IEEE754 issues will become a factor). However, if you're reducing the size of your mesh substantially you might well be finding that the rendered geometry is mapping to the same Z values.

hth
Jack

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Just complementing jollyjeffers's comments:

Z-buffer is a non-linear method. It gives you a lot of precision close to the camera's eye and little precision off in the distance. So, put the near frustum plane as far from the camera's eye as you can tolerate.

Two solutions:

1) Use w-buffer method instead of z-buffer (some cards don't support it):

pDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_USEW);


2) Increase the z-position of the near frustum plane. For example:

D3DXMatrixPerspectiveFovLH(&mat, 0.25f*3.141592654f, fAspect, 5.0f, 10000.0f);

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

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

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!