Sign in to follow this  
Say

why this rendering bug!

Recommended Posts

Say    122
Looking at this image: i've create two swap chains it works fine if the second one is smaller the first, but if i size in width the second panel (second swap chain) the scene in this panel is rendered bad. Some face is transparent, empty without surface. I see the within of the mesh. Why? What do i wrong?

Share this post


Link to post
Share on other sites
Say    122
Quote:
Do you have the z-buffer write and tests enabled?

sorry, i'm newbie about direct3d, can you indicate me better what do you mean?

Anyway i use this code:
i use this lines:
// on scene preparing
device.RenderState.ZBufferEnabled = true;

//on rendering
device.Clear(Clear.Target | Clear.ZBuffer, Color.Gray, 1.0f, 0);

other?

Share this post


Link to post
Share on other sites
neneboricua19    634
What Kamikaze is talking about is that you must create a depth buffer when you first create the Direct3D device. When you call IDirect3D9::CreateDevice, make sure that the "EnableAutoDepthStencil" member of the PRESENT_PARAMETERS structure you pass in is set to TRUE.

This instructs the Direct3D object to create a device that has a depth buffer.

neneboricua

Share this post


Link to post
Share on other sites
jollyjeffers    1570
Kamikaze15 is correct - you've got some depth buffering issues there [smile]

You're using MDX so I'm not sure the exact syntax, but the "Present Parameters" that you pass in to your CreateDevice call (new Device(...) in MDX?) should have an "AutoDepthStencilFormat" field - try setting this to D3DFMT_D16.

There is another possible cause... your projection matrix. With a value of 0 for the near plane you can end up with unstable/incorrect depth values - if the first suggestion doesn't work for you, post your code for creating a projection matrix.

hth
Jack

Share this post


Link to post
Share on other sites
Say    122
i make all that you tell becouse i make this:
//for the first swap chain (directly to the device object)
presentParams[0].EnableAutoDepthStencil = true;
presentParams[0].AutoDepthStencilFormat = DepthFormat.D16;
...
device = new Device(..., presentParams[0]);

//for the second swap chain
presentParams[1].EnableAutoDepthStencil = true;
presentParams[1].AutoDepthStencilFormat = DepthFormat.D16;


Then this is my projection code:

float scale = 1.0f;
Vector3 pos = new Vector3();
Vector3 camPos = new Vector3();
Vector3 lookAt = new Vector3(0.0f, 0.0f, 5.0f);
Vector3 camUp = new Vector3(0.0f, 1.0f, 0.0f);

device.Transform.Project = Matrix.PerspectiveForLH((float)Math.PI / 4, 1.0f, 1.0f, 100.0f);
device.Transform.View = Matrix.LookAtLH(camPos, lookAt, camUp);
device.Transform.World = Matrix.Scaling(scale,scale,scale)*Matrix.Transform(0f, 0f, 0f)*Matrix.RotationY(Environment.TickCount/1000.0f);

Share this post


Link to post
Share on other sites
mdias    823
Maybe you have your camera too near from the object and a very large far clipping plane, which causes inaccuracies in the depth buffer.
Try to make your far clipping plane 10.0f in the projection matrix.

Share this post


Link to post
Share on other sites
mdias    823
Here's the modified version of your code

float scale = 1.0f;
Vector3 pos = new Vector3();
Vector3 camPos = new Vector3();
Vector3 lookAt = new Vector3(0.0f, 0.0f, 5.0f);
Vector3 camUp = new Vector3(0.0f, 1.0f, 0.0f);

device.Transform.Project = Matrix.PerspectiveForLH((float)Math.PI / 4, 1.0f, 1.0f, 10.0f); // <-- here is the change
device.Transform.View = Matrix.LookAtLH(camPos, lookAt, camUp);
device.Transform.World = Matrix.Scaling(scale,scale,scale)*Matrix.Transform(0f, 0f, 0f)*Matrix.RotationY(Environment.TickCount/1000.0f);



I don't know MDX, so I hope I modified it in the right place.

Share this post


Link to post
Share on other sites
Armadon    1091
I would be beneficial if you use a nicer Depth/Stencil buffer set. Usually a Depth buffer of 24 bits and Stencil buffer of 8. The setup would then look like this.


presentParams.AutoDepthStencilFormat = DepthFormat.D24S8;
presentParams.EnableAutoDepthStencil = true;

//Also when creating a Projection transformation matrix.
device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, 1.3f, 1.0f, 1000.0f);



This should push you in the right direction and get rid of your Depth issues. Make sure to clear the depth buffer, stencil buffer and target when rendering.


device.Clear(ClearFlags.Target | ClearFlags.ZBuffer | ClearFlags.Stencil, color, 1.0f, 0);



I hope this helps.
Take care.

Share this post


Link to post
Share on other sites
Say    122
the code modified doesn't improve the result.
you can try my .exe http://www.freestylebitonto.com/debug.rar

this is the complete code:

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;


namespace prova_3d
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class prova_3dForm : System.Windows.Forms.Form
{
private System.Windows.Forms.Splitter splitter1;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;

Device device = null;
SwapChain sc_0 = null;
SwapChain sc_1 = null;
Mesh mesh = null;
Material[] meshMaterials; // Materials for the mesh
Texture[] meshTextures; // Textures for the mesh

private System.Windows.Forms.Panel panel0;
private System.Windows.Forms.Panel panel1;
private bool running;
private bool initialized = false;
private bool can_draw = false;

string error_message = "";

struct Vertex
{
float x, y, z;
float nx, ny, nz;
int diffuse;

/*enum FVF
{
FVF_flags = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE
};*/

}

public prova_3dForm()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();

//
// TODO: Add any constructor code after InitializeComponent call
//
Init();
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.panel0 = new System.Windows.Forms.Panel();
this.splitter1 = new System.Windows.Forms.Splitter();
this.panel1 = new System.Windows.Forms.Panel();
this.SuspendLayout();
//
// panel0
//
this.panel0.Dock = System.Windows.Forms.DockStyle.Left;
this.panel0.Location = new System.Drawing.Point(0, 0);
this.panel0.Name = "panel0";
this.panel0.Size = new System.Drawing.Size(192, 374);
this.panel0.TabIndex = 0;
this.panel0.Resize += new System.EventHandler(this.panel0_Resize);
//
// splitter1
//
this.splitter1.BackColor = System.Drawing.Color.DimGray;
this.splitter1.Location = new System.Drawing.Point(192, 0);
this.splitter1.Name = "splitter1";
this.splitter1.Size = new System.Drawing.Size(5, 374);
this.splitter1.TabIndex = 1;
this.splitter1.TabStop = false;
//
// panel1
//
this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.panel1.Location = new System.Drawing.Point(197, 0);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(363, 374);
this.panel1.TabIndex = 2;
this.panel1.Resize += new System.EventHandler(this.panel1_Resize);
//
// Sake3DForm
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(560, 374);
this.Controls.Add(this.panel1);
this.Controls.Add(this.splitter1);
this.Controls.Add(this.panel0);
this.Name = "Form1";
this.Text = "Form1";
this.Closing += new System.ComponentModel.CancelEventHandler(this.Form1_Closing);
this.ResumeLayout(false);

}
#endregion

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
prova_3dForm sf = new prova_3dForm();
sf.Show();

while(sf.running)
{
if( sf.can_draw )
sf.Render();
Application.DoEvents();
}
}

private bool CreateDevice()
{
try{
PresentParameters presentParams = new PresentParameters();

presentParams.Windowed = true;
presentParams.BackBufferCount = 1;
presentParams.SwapEffect = SwapEffect.Discard;
presentParams.EnableAutoDepthStencil = true;
presentParams.AutoDepthStencilFormat = DepthFormat.D24S8;
presentParams.DeviceWindowHandle = panel0.Handle;
presentParams.BackBufferWidth = panel0.Width;
presentParams.BackBufferHeight = panel0.Height;

SetDevice(presentParams);

sc_0 = new SwapChain(device, presentParams);
}
catch
{
error_message += "errore nella creazione del device" + "\n";
return false;
}
return true;
}

private void SetDevice(PresentParameters presentParams)
{
device = new Device(0, DeviceType.Hardware, panel0,
CreateFlags.SoftwareVertexProcessing, presentParams);
device.SetRenderState(RenderStates.ZEnable, true);
device.DeviceLost += new System.EventHandler(this.DeviceLost);
device.DeviceResizing += new CancelEventHandler(this.DeviceResizingEventHandler);
device.DeviceReset += new System.EventHandler(this.ResetDevice);
this.ResetDevice(device, null);
}

private bool CheckShaderSupport()
{
Version v1_1 = new Version(1,1); // check version is at least shader 1.1

// retrieve the device caps
Caps caps = Manager.GetDeviceCaps(0, DeviceType.Hardware);

// check the supported shader version
if ((caps.VertexShaderVersion >= v1_1) && (caps.PixelShaderVersion >= v1_1))
{
return true;
}

error_message += "errore nella creazione del supporto" + "\n";
return false;
}

private bool CreateAdditionalSwapChains()
{
try
{
// questo è il primo
sc_0 = device.GetSwapChain(0);

// ora creo il secondo
PresentParameters presentParams = new PresentParameters();
presentParams.BackBufferCount = 1;
presentParams.Windowed = true;
presentParams.DeviceWindowHandle = panel1.Handle;
presentParams.SwapEffect = SwapEffect.Discard;
presentParams.EnableAutoDepthStencil = true;
presentParams.AutoDepthStencilFormat = DepthFormat.D24S8;
presentParams.BackBufferWidth = panel1.Width;
presentParams.BackBufferHeight = panel1.Height;

sc_1 = new SwapChain(device, presentParams);
}
catch
{
error_message += "errore nella creazione dell'additional swap chain" + "\n";
return false;
}
initialized = true;
return true;
}

Mesh m1;

private bool PrepareScene()
{
try
{
ExtendedMaterial[] materials = null;

// Turn on the z-buffer.
device.RenderState.ZBufferEnable = true;

// Turn on ambient lighting.
device.RenderState.Ambient = System.Drawing.Color.White;
device.RenderState.FillMode = (FillMode)0;

meshTextures = null;
mesh = Mesh.FromFile(Application.StartupPath + @"\mesh.x",
MeshFlags.SystemMemory,
device,
out materials);
if (meshTextures == null)
{
// Extract the material properties and texture names.
meshTextures = new Texture[materials.Length];
meshMaterials = new Material[materials.Length];
for( int i=0; i<materials.Length; i++ )
{
meshMaterials[i] = materials[i].Material3D;

// Set the ambient color for the material. Direct3D
// does not do this by default.
meshMaterials[i].Ambient = meshMaterials[i].Diffuse;

// Create the texture.
meshTextures[i] = TextureLoader.FromFile(device,
materials[i].TextureFilename);
}
}
}
catch
{
error_message += "errore nel caricare la mesh" + "\n";
return false;
}

return true;
}

private void Init()
{
if( CreateDevice() && CheckShaderSupport() && CreateAdditionalSwapChains() )
{
running = true;
can_draw = true;
}
else
MessageBox.Show(error_message);

}

private void UpdateParameters_0()
{
PresentParameters presentParams = new PresentParameters();

presentParams.Windowed = true;
presentParams.BackBufferCount = 1;
presentParams.SwapEffect = SwapEffect.Discard;
presentParams.EnableAutoDepthStencil = true;
presentParams.AutoDepthStencilFormat = DepthFormat.D24S8;
presentParams.DeviceWindowHandle = panel0.Handle;
presentParams.BackBufferWidth = panel0.Width;
presentParams.BackBufferHeight = panel0.Height;

SetDevice(presentParams);

sc_0 = new SwapChain(device, presentParams);
}
private void UpdateParameters_1()
{
// ora creo il secondo
PresentParameters presentParams1 = new PresentParameters();
presentParams1.Windowed = true;
presentParams1.BackBufferCount = 1;
presentParams1.SwapEffect = SwapEffect.Discard;
presentParams1.EnableAutoDepthStencil = true;
presentParams1.DeviceWindowHandle = panel1.Handle;
presentParams1.AutoDepthStencilFormat = DepthFormat.D24S8;
presentParams1.BackBufferWidth = panel1.Width;
presentParams1.BackBufferHeight = panel1.Height;

sc_1 = new SwapChain(device, presentParams1);
}

private void Render()
{
SetupMatrices(panel0.Width, panel0.Height);
Render_panel0();
Render_panel1();
}

void SetupMatrices(int w, int h)
{
float scale = 1.0f; // The gun is gigantic, so let's scale it down a bit
Vector3 pos = new Vector3(); // Let's display at 0, 0,
Vector3 camPos = new Vector3(0.0f, 0.0f, 5.0f);
Vector3 lookAt = new Vector3(0.0f, 0.0f, 0.0f); // We are facing 0, 0, 0, so we can see the model
Vector3 camUp = new Vector3(0.0f, 1.0f, 0.0f); // Up vector of the cam

// Setup the camera
device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, 1.0f, 1.0f, 10.0f );
device.Transform.View = Matrix.LookAtLH(camPos, lookAt, camUp);

// Display our model
device.Transform.World = Matrix.Scaling(scale, scale, scale)*Matrix.Translation(0f, 0f, 0f)*Matrix.RotationY(Environment.TickCount/1000.0f);
}

private void Render_panel0()
{
Surface backbuffer;
backbuffer = sc_0.GetBackBuffer(0, BackBufferType.Mono);
device.SetRenderTarget(0, backbuffer);
device.Clear(ClearFlags.Target | ClearFlags.ZBuffer | ClearFlags.Stencil, Color.Gray, 1.0f, 0);
device.BeginScene();
try
{
for (int m = 0; m < meshTextures.Length; ++m)
{
device.Material = meshMaterials[m];
device.SetTexture(0, meshTextures[m]);
mesh.DrawSubset(m);
}
}
catch(Direct3DXException ex)
{
running = false;
MessageBox.Show(ex.ToString());
}
finally
{
device.EndScene();
sc_0.Present();
backbuffer.Dispose();
}
}

private void Render_panel1()
{
Surface backbuffer;
backbuffer = sc_1.GetBackBuffer(0, BackBufferType.Mono);
device.SetRenderTarget(0, backbuffer);
device.Clear(ClearFlags.Target | ClearFlags.ZBuffer | ClearFlags.Stencil, Color.Gray, 1.0f, 0);
device.BeginScene();
try
{
for (int m = 0; m < meshTextures.Length; ++m)
{
device.Material = meshMaterials[m];
device.SetTexture(0, meshTextures[m]);
mesh.DrawSubset(m);
}
}
catch(Direct3DXException ex)
{
running = false;
MessageBox.Show(ex.ToString());
}
finally
{
device.EndScene();
sc_1.Present();
backbuffer.Dispose();
}
}

private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
running = false;
}

private void DeviceLost(object sender, System.EventArgs e)
{
//TODO: forse andrebbero le seguenti 2 o 4 righe
//device = ((Device)sender);
//PrepareScene();
//can_draw = false;
//device.CheckCooperativeLevel();
}

private void DeviceResizingEventHandler(object sender, System.ComponentModel.CancelEventArgs e)
{
e.Cancel = true;
}

private void ResetDevice(object sender, System.EventArgs e)
{
device = ((Device)sender);
PrepareScene();
}

private void panel0_Resize(object sender, System.EventArgs e)
{
can_draw = this.WindowState != FormWindowState.Minimized;

if(initialized && can_draw)
{
UpdateParameters_0();
PrepareScene();
}
}

private void panel1_Resize(object sender, System.EventArgs e)
{
can_draw = this.WindowState != FormWindowState.Minimized;

if(initialized && can_draw)
{
UpdateParameters_1();
//PrepareScene();
}
}

}
}






please help me to find the bug, thanks.

Share this post


Link to post
Share on other sites
weasalmongler    205
Maybe it is your winding order on the triangles.

If you have backface culling enabled and have the wind order the wrong way around then it will draw the interior of the surfaces rather than the outside and you will get strange effects similar to what you have.

You could try adding

device.SetRenderState(D3DRENDERSTATE_CULLMODE,D3DCULL_CCW);

or

device.SetRenderState(D3DRENDERSTATE_CULLMODE,D3DCULL_CW);

to your initialization code.


Also make sure that you call

device.SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);

in your startup code.

Share this post


Link to post
Share on other sites
Say    122
if that you told is right the problem had to happen also in the other swap chain becouse it is the same scene rendered, so if the problem was the index buffer or the way of closing of faces it had to happen also for the first chain.
Futhermore it happen just if i resize the second render panel and it became bigger the first one.
It is very strange but they are many months i'm troubling about it!
Please give me some advice.

Share this post


Link to post
Share on other sites
mdias    823
I had a look through your code and didn't find anything wrong or why I'm getting that filenotfound exception. However I don't know MDX.

Have you tried running that application on another PC?

I'm sorry I can't help you more.

Share this post


Link to post
Share on other sites
Armadon    1091
Quote:
Original post by Kamikaze15
I had a look through your code and didn't find anything wrong or why I'm getting that filenotfound exception. However I don't know MDX.
Have you tried running that application on another PC?
I'm sorry I can't help you more.


This normally happens if you don't have MDX installed.

On the other side of the problem. I have had a look at the app and I cannot seem to recreate the problem you are getting. Resizing the window with the splitter doesn't result in the kind of effect you were showing. What you could do to debug this is try just with one backbuffer and then create a swap chain again and see if the problem occurs.

I hope this helps (probably doesn't..)
But either way it's information you can use.
Take care.

Share this post


Link to post
Share on other sites
Say    122
[quote]
Quote:
Original post by Kamikaze15
What you could do to debug this is try just with one backbuffer and then create a swap chain again and see if the problem occurs.


This problem happen on my notebook (Centrino 1,4 ghz ATI radeon 128 mb), if i try on the other pc (P4 3,2 ghz 128 mb radeon 9550) i get other bad render error!
But why?

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